Skip to content

Commit

Permalink
Detect modification for resources that does not use generation
Browse files Browse the repository at this point in the history
Signed-off-by: Tamal Saha <tamal@appscode.com>
  • Loading branch information
tamalsaha committed Oct 10, 2024
1 parent 175fd7e commit c504bc3
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 8 deletions.
13 changes: 11 additions & 2 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"reflect"
"strings"

"kmodules.xyz/client-go/meta"

"github.com/pkg/errors"
kerr "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
Expand Down Expand Up @@ -116,8 +118,15 @@ func CreateOrPatch(ctx context.Context, c client.Client, obj client.Object, tran
}

vt := kutil.VerbUnchanged
if cur.GetGeneration() != mod.GetGeneration() {
vt = kutil.VerbPatched
if mod.GetGeneration() > 0 {
if cur.GetGeneration() != mod.GetGeneration() {
vt = kutil.VerbPatched
}
} else {
// Secret, ServiceAccount etc resources do not use metadata.generation
if meta.ObjectHash(cur) != meta.ObjectHash(mod) {
vt = kutil.VerbPatched
}
}
assign(obj, mod)
return vt, nil
Expand Down
25 changes: 19 additions & 6 deletions meta/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ func ResourceHash(obj metav1.Object) string {
h := xxh3.New()
_, _ = h.WriteString(string(obj.GetUID()))
_, _ = h.WriteString(",")
_, _ = h.WriteString(strconv.FormatInt(obj.GetGeneration(), 10))
if obj.GetGeneration() > 0 {
_, _ = h.WriteString(strconv.FormatInt(obj.GetGeneration(), 10))
} else {
_, _ = h.WriteString(ObjectHash(obj))
}
return strconv.FormatUint(h.Sum64(), 10)
}

Expand All @@ -57,11 +61,20 @@ func ObjectHash(in metav1.Object) string {
obj["annotations"] = data
}

st := structs.New(in)
for _, field := range st.Fields() {
fieldName := field.Name()
if fieldName != "ObjectMeta" && fieldName != "TypeMeta" && fieldName != "Status" {
obj[fieldName] = field.Value()
u, isUnstructured := in.(*unstructured.Unstructured)
if isUnstructured {
for fieldName, v := range u.UnstructuredContent() {
if fieldName != "metadata" && fieldName != "apiVersion" && fieldName != "kind" && fieldName != "status" {
obj[fieldName] = v
}
}
} else {
st := structs.New(in)
for _, field := range st.Fields() {
fieldName := field.Name()
if fieldName != "ObjectMeta" && fieldName != "TypeMeta" && fieldName != "Status" {
obj[fieldName] = field.Value()
}
}
}

Expand Down

0 comments on commit c504bc3

Please sign in to comment.