Skip to content

Commit 4236369

Browse files
authored
Add option to ignore status field diffs when checking object matching (#21)
1 parent 8f64722 commit 4236369

File tree

6 files changed

+64
-18
lines changed

6 files changed

+64
-18
lines changed

go.mod

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ require (
1010
github.com/goph/emperror v0.17.2
1111
github.com/imdario/mergo v0.3.7 // indirect
1212
github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be
13-
github.com/modern-go/reflect2 v1.0.1
1413
github.com/pkg/errors v0.8.1
1514
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 // indirect
1615
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 // indirect

go.sum

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
8282
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
8383
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
8484
github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
85+
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
8586
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
8687
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367 h1:ScAXWS+TR6MZKex+7Z8rneuSJH+FSDqd6ocQyl+ZHo4=
8788
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
@@ -199,8 +200,6 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r
199200
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
200201
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
201202
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
202-
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk=
203-
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
204203
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc h1:gkKoSkUmnU6bpS/VhkuO27bzQeSA51uaEfbOW5dNb68=
205204
golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
206205
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -264,23 +263,15 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
264263
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
265264
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
266265
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
267-
k8s.io/api v0.0.0-20190704095032-f4ca3d3bdf1d h1:X3GqeHwOBOJa0O7jrPobw6MGLMwthSnA/sM86ENzbCo=
268-
k8s.io/api v0.0.0-20190704095032-f4ca3d3bdf1d/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
269266
k8s.io/api v0.15.7 h1:Qoun2090uLk9jvaXX6I5b02mh8bKrluPcbvsGrOfAKE=
270267
k8s.io/api v0.15.7/go.mod h1:a/tUxscL+UxvYyA7Tj5DRc8ivYqJIO1Y5KDdlI6wSvo=
271-
k8s.io/apiextensions-apiserver v0.0.0-20190801143813-8b5f3a974f92 h1:+u+St6CJcJVpQIRYfdXhrMnUP7h8f/uiZtP8HKtaY40=
272-
k8s.io/apiextensions-apiserver v0.0.0-20190801143813-8b5f3a974f92/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE=
273268
k8s.io/apiextensions-apiserver v0.15.7 h1:7HeYMxRPsw3fAplLC54NTbszBLlGw3j9rZE5caAP5JY=
274269
k8s.io/apiextensions-apiserver v0.15.7/go.mod h1:ctb/NYtsiBt6CGN42Z+JrOkxi9nJYaKZYmatJ6SUy0Y=
275-
k8s.io/apimachinery v0.0.0-20190704094733-8f6ac2502e51 h1:Nuz3yWD9v9dVvDiVSBIah+B+pxkxQxtuBAx2712t7tQ=
276-
k8s.io/apimachinery v0.0.0-20190704094733-8f6ac2502e51/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
277270
k8s.io/apimachinery v0.15.7 h1:H6pN003RwDju/3BzRGuymY4ymvMjHNbD8MVWhtDeaOI=
278271
k8s.io/apimachinery v0.15.7/go.mod h1:Xc10RHc1U+F/e9GCloJ8QAeCGevSVP5xhOhqlE+e1kM=
279272
k8s.io/apiserver v0.15.7/go.mod h1:d5Dbyt588GbBtUnbx9fSK+pYeqgZa32op+I1BmXiNuE=
280273
k8s.io/client-go v0.15.7 h1:ROclobh8vRf6kaKuhRKVXNWnBG+RthyKmWoM4kwWSI8=
281274
k8s.io/client-go v0.15.7/go.mod h1:QMNB76d3lKPvPQdOOnnxUF693C3hnCzUbC2umg70pWA=
282-
k8s.io/client-go v11.0.1-0.20190516230509-ae8359b20417+incompatible h1:bK03DJulJi9j05gwnXUufcs2j7h4M85YFvJ0dIlQ9k4=
283-
k8s.io/client-go v11.0.1-0.20190516230509-ae8359b20417+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
284275
k8s.io/code-generator v0.15.7/go.mod h1:G8bQwmHm2eafm5bgtX67XDZQ8CWKSGu9DekI+yN4Y5I=
285276
k8s.io/component-base v0.15.7/go.mod h1:iunfIII6uq3NC3S/EhBpKv8+eQ76vwlOYdFpyIeBk7g=
286277
k8s.io/gengo v0.0.0-20190116091435-f8a0810f38af/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=

integration_test.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func TestIntegration(t *testing.T) {
9494
pod := i.(*v1.Pod)
9595
pod.Spec.Containers[0].Command = []string{"1", "2", "3"}
9696
}),
97-
NewTestDiff("pod does not match when a field shozuld be removed only if it existed before",
97+
NewTestDiff("pod does not match when a field should be removed only if it existed before",
9898
&v1.Pod{
9999
ObjectMeta: standardObjectMeta(),
100100
Spec: v1.PodSpec{
@@ -564,6 +564,21 @@ func TestIntegration(t *testing.T) {
564564
MinAvailable: intstrRef(intstr.FromInt(1)),
565565
},
566566
}),
567+
NewTestMatch("pdb match even though status changes",
568+
&v1beta12.PodDisruptionBudget{
569+
ObjectMeta: standardObjectMeta(),
570+
Spec: v1beta12.PodDisruptionBudgetSpec{
571+
MinAvailable: intstrRef(intstr.FromInt(1)),
572+
},
573+
}).
574+
withRemoteChange(func(i interface{}) {
575+
pdb := i.(*v1beta12.PodDisruptionBudget)
576+
pdb.Status.CurrentHealthy = 1
577+
pdb.Status.DesiredHealthy = 1
578+
pdb.Status.ExpectedPods = 1
579+
pdb.Status.PodDisruptionsAllowed = 0
580+
pdb.Status.ObservedGeneration = 1
581+
}),
567582
NewTestMatch("pvc match",
568583
&v1.PersistentVolumeClaim{
569584
ObjectMeta: standardObjectMeta(),

main_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ func testMatchOnObject(testItem *TestItem) error {
408408
testItem.localChange(newObject)
409409
}
410410

411-
patchResult, err := patch.DefaultPatchMaker.Calculate(existing.(runtime.Object), newObject.(runtime.Object))
411+
patchResult, err := patch.DefaultPatchMaker.Calculate(existing.(runtime.Object), newObject.(runtime.Object), patch.IgnoreStatusFields())
412412
if err != nil {
413413
return err
414414
}

patch/deletenull.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,24 @@ import (
2424
"k8s.io/apimachinery/pkg/util/intstr"
2525
)
2626

27+
type CalculateOption func([]byte, []byte) ([]byte, []byte, error)
28+
29+
func IgnoreStatusFields() CalculateOption {
30+
return func(current, modified []byte) ([]byte, []byte, error) {
31+
current, err := deleteStatusField(current)
32+
if err != nil {
33+
return []byte{}, []byte{}, emperror.Wrap(err, "could not delete status field from current byte sequence")
34+
}
35+
36+
modified, err = deleteStatusField(modified)
37+
if err != nil {
38+
return []byte{}, []byte{}, emperror.Wrap(err, "could not delete status field from modified byte sequence")
39+
}
40+
41+
return current, modified, nil
42+
}
43+
}
44+
2745
func init() {
2846
// k8s.io/apimachinery/pkg/util/intstr.IntOrString behaves really badly
2947
// from JSON marshaling point of view, it can't be empty basically.
@@ -136,6 +154,21 @@ func deleteNullInSlice(m []interface{}) ([]interface{}, error) {
136154
return filteredSlice, nil
137155
}
138156

157+
func deleteStatusField(obj []byte) ([]byte, error) {
158+
var objectMap map[string]interface{}
159+
err := json.Unmarshal(obj, &objectMap)
160+
if err != nil {
161+
return []byte{}, emperror.Wrap(err, "could not unmarshal byte sequence")
162+
}
163+
delete(objectMap, "status")
164+
obj, err = json.Marshal(objectMap)
165+
if err != nil {
166+
return []byte{}, emperror.Wrap(err, "could not marshal byte sequence")
167+
}
168+
169+
return obj, nil
170+
}
171+
139172
func isZero(v reflect.Value) bool {
140173
switch v.Kind() {
141174
default:

patch/patch.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package patch
1616

1717
import (
1818
"fmt"
19+
1920
json "github.com/json-iterator/go"
2021

2122
"github.com/goph/emperror"
@@ -37,20 +38,27 @@ func NewPatchMaker(annotator *Annotator) *PatchMaker {
3738
}
3839
}
3940

40-
func (p *PatchMaker) Calculate(currentObject, modifiedObject runtime.Object) (*PatchResult, error) {
41+
func (p *PatchMaker) Calculate(currentObject, modifiedObject runtime.Object, opts ...CalculateOption) (*PatchResult, error) {
4142
current, err := json.Marshal(currentObject)
4243
if err != nil {
4344
return nil, emperror.Wrap(err, "Failed to convert current object to byte sequence")
4445
}
4546

46-
current, _, err = DeleteNullInJson(current)
47+
modified, err := json.Marshal(modifiedObject)
4748
if err != nil {
48-
return nil, emperror.Wrap(err, "Failed to delete null from current object")
49+
return nil, emperror.Wrap(err, "Failed to convert current object to byte sequence")
4950
}
5051

51-
modified, err := json.Marshal(modifiedObject)
52+
for _, opt := range opts {
53+
current, modified, err = opt(current, modified)
54+
if err != nil {
55+
return nil, emperror.Wrap(err, "Failed to apply option function")
56+
}
57+
}
58+
59+
current, _, err = DeleteNullInJson(current)
5260
if err != nil {
53-
return nil, emperror.Wrap(err, "Failed to convert current object to byte sequence")
61+
return nil, emperror.Wrap(err, "Failed to delete null from current object")
5462
}
5563

5664
modified, _, err = DeleteNullInJson(modified)

0 commit comments

Comments
 (0)