wI2L/jsondiff

I am looking for a Stronger jsonPatch apply lib

zhangguanzhang opened this issue · 8 comments

usefor Kubernetes Dynamic Admission Controller

package main

import (
	"encoding/json"
	"fmt"

	jsonpatch "github.com/xxxx/json-patch"
	corev1 "k8s.io/api/core/v1"

)

func main()  {

	var pod = corev1.Pod{
		Spec:       corev1.PodSpec{
			Volumes: []corev1.Volume{
				{
					Name: "default-token-lsh6v",
					VolumeSource: corev1.VolumeSource{
						Secret: &corev1.SecretVolumeSource{
							SecretName: "default-token-lsh6v",
						},
					},
				},
			},

		},
	}

	podBytes, _ := json.Marshal(&pod)

	fmt.Printf("old document: %s\n", podBytes)

	patchJSON := []byte(`[
   {
      "op":"add",
      "path":"/spec",
      "value":{
         "dnsConfig":{
            "options":[
               {
                  "name":"single-request-reopen"
               }
            ]
         }
      }
   },
   {
      "op":"add",
      "path":"/spec/volumes/-",
      "value":{
         "name":"default-token-lsh6v1111",
         "secret":{
            "secretName":"default-token-lsh6v1111"
         }
      }
   }
]`)
	patch, err := jsonpatch.DecodePatch(patchJSON)
	if err != nil {
		panic(err)
	}
	modified, err := patch.Apply(podBytes)
	if err != nil {
		panic(err)
	}
	fmt.Printf("Modified document: %s\n", modified)

}

expect result json is:

{
   "metadata":{
      "creationTimestamp":null
   },
   "spec":{
      "dnsConfig":{
         "options":[
            {
               "name":"single-request-reopen"
            }
         ]
      },
      "containers":null,
      "volumes":[
         {
            "name":"default-token-lsh6v",
            "secret":{
               "secretName":"default-token-lsh6v"
            }
         },
         {
            "name":"default-token-lsh6v1111",
            "secret":{
               "secretName":"default-token-lsh6v1111"
            }
         }
      ]
   }
}

also, I expect:

   {
      "op":"append",
      "path":"/spec/containers/*/env",
      "value":{
         "name":"KEY",
         "value": "VALUE"
      }
   }

this will append a env to all containers ,not override

wI2L commented

This package is for generating JSON Patches, not applying them, so I'm not sure what's your question. Moreover, the append OP isn't specified by the JSON Patch RFC, you should use an add operation with a path like /path/to/element/- to append a the end of an array.

the first op add will add a dnsConfig to override spec.

wI2L commented

Sorry, is this related to this package ? I still can't tell from your question. Are you generating a patch with jsondiff ?

patch:

[
   {
      "op":"add",
      "path":"/bar",
      "value":{
         "test111111111":{
            "a":1,
            "b":2
         }
      }
   }
]

data:

{
  "bar" : {
    "test": 1
    }
}

result:

{
  "bar" : {
    "test111111111" : {
      "a" : 1,
      "b" : 2
    }
  }
}

I expect there has a stronger JsonPatch lib to get this result:

{
  "bar" : {
    "test": 1,
    "test111111111" : {
      "a" : 1,
      "b" : 2
    }
  }
}

Assuming that there is a super jsonPatch language, we can use it to change the json of the pod, and then use jsonDiff to generate a regular jsonPatch. The user only needs to write this super jsonPatch to change the properties of the pod in the access control of the pod.

wI2L commented

Your patch is valid, see https://tools.ietf.org/html/rfc6902#section-4.1

If the target location specifies an object member that does exist, that member's value is replaced.

I still don't get the link between your issue and this package.

I know this, I mean you can construct a middle-layer jsonPatch, and finally generate a standard jsonPatch

wI2L commented

I still don't get what is your point. Are you reporting an issue with the package, or proposing a feature ? You are talking about a "super jsonPatch", but that seems hypothetical to me, there's no such thing that I'm aware of. This package follows the JSON Patch RFC.

Please provide a full explanation of what your trying to achieve, and why, so I can understand what we're talking about, otherwise I won't be able to provide a constructive answer.

Thanks