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

Don't set resourceVersion for objects to be created #611

Merged
merged 2 commits into from
Dec 10, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 62 additions & 5 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ func NewUncachedClient(cfg *rest.Config, funcs ...func(*runtime.Scheme) error) (
}

type (
TransformFunc func(obj client.Object, createOp bool) client.Object
TransformFuncE func(obj client.Object, createOp bool) (client.Object, error)
TransformStatusFunc func(obj client.Object) client.Object
TransformFunc func(obj client.Object, createOp bool) client.Object
TransformFuncE func(obj client.Object, createOp bool) (client.Object, error)
PatchFunc func(obj client.Object) client.Object
PatchFuncE func(obj client.Object) (client.Object, error)
)

func CreateOrPatchE(ctx context.Context, c client.Client, obj client.Object, transform TransformFuncE, opts ...client.PatchOption) (kutil.VerbType, error) {
Expand Down Expand Up @@ -96,6 +97,7 @@ func CreateOrPatchE(ctx context.Context, c client.Client, obj client.Object, tra
if err != nil {
return kutil.VerbUnchanged, err
}
mod.SetResourceVersion("")
err = c.Create(ctx, mod, createOpts...)
if err != nil {
return kutil.VerbUnchanged, err
Expand Down Expand Up @@ -146,6 +148,51 @@ func CreateOrPatch(ctx context.Context, c client.Client, obj client.Object, tran
}, opts...)
}

func PatchE(ctx context.Context, c client.Client, obj client.Object, transform PatchFuncE, opts ...client.PatchOption) (kutil.VerbType, error) {
gvk, err := apiutil.GVKForObject(obj, c.Scheme())
if err != nil {
return kutil.VerbUnchanged, errors.Wrapf(err, "failed to get GVK for object %T", obj)
}

_, unstructuredObj := obj.(*unstructured.Unstructured)

var patch client.Patch
if isOfficialTypes(gvk.Group) && !unstructuredObj {
patch = client.StrategicMergeFrom(obj)
} else {
patch = client.MergeFrom(obj)
}
mod, err := transform(obj.DeepCopyObject().(client.Object))
if err != nil {
return kutil.VerbUnchanged, err
}
err = c.Patch(ctx, mod, patch, opts...)
if err != nil {
return kutil.VerbUnchanged, err
}

vt := kutil.VerbUnchanged
if mod.GetGeneration() > 0 {
if obj.GetGeneration() != mod.GetGeneration() {
vt = kutil.VerbPatched
}
} else {
// Secret, ServiceAccount etc resources do not use metadata.generation
if meta.ObjectHash(obj) != meta.ObjectHash(mod) {
vt = kutil.VerbPatched
}
}
assign(obj, mod)
return vt, nil
}

func Patch(ctx context.Context, c client.Client, obj client.Object, transform PatchFunc, opts ...client.PatchOption) (kutil.VerbType, error) {
return PatchE(ctx, c, obj, func(obj client.Object) (client.Object, error) {
transform(obj)
return obj, nil
}, opts...)
}

func assign(target, src any) {
srcValue := reflect.ValueOf(src)
if srcValue.Kind() == reflect.Pointer {
Expand All @@ -154,7 +201,7 @@ func assign(target, src any) {
reflect.ValueOf(target).Elem().Set(srcValue)
}

func PatchStatus(ctx context.Context, c client.Client, obj client.Object, transform TransformStatusFunc, opts ...client.SubResourcePatchOption) (kutil.VerbType, error) {
func PatchStatusE(ctx context.Context, c client.Client, obj client.Object, transform PatchFuncE, opts ...client.SubResourcePatchOption) (kutil.VerbType, error) {
cur := obj.DeepCopyObject().(client.Object)
key := types.NamespacedName{
Namespace: cur.GetNamespace(),
Expand All @@ -171,7 +218,10 @@ func PatchStatus(ctx context.Context, c client.Client, obj client.Object, transf
// - application/merge-patch+json,
// - application/apply-patch+yaml
patch := client.MergeFrom(cur)
mod := transform(cur.DeepCopyObject().(client.Object))
mod, err := transform(cur.DeepCopyObject().(client.Object))
if err != nil {
return kutil.VerbUnchanged, err
}
err = c.Status().Patch(ctx, mod, patch, opts...)
if err != nil {
return kutil.VerbUnchanged, err
Expand All @@ -180,6 +230,13 @@ func PatchStatus(ctx context.Context, c client.Client, obj client.Object, transf
return kutil.VerbPatched, nil
}

func PatchStatus(ctx context.Context, c client.Client, obj client.Object, transform PatchFunc, opts ...client.SubResourcePatchOption) (kutil.VerbType, error) {
return PatchStatusE(ctx, c, obj, func(obj client.Object) (client.Object, error) {
transform(obj)
return obj, nil
}, opts...)
}

func isOfficialTypes(group string) bool {
return !strings.ContainsRune(group, '.')
}
Expand Down
Loading