func (h *Helper) patch(ctx context.Context, obj runtime.Object) error {
	if !h.shouldPatch("metadata") && !h.shouldPatch("spec") {
		return nil
	}
	beforeObject, afterObject, err := h.calculatePatch(obj, specPatch)
	if err != nil {
		return err
	}
	return h.client.Patch(ctx, afterObject, client.MergeFrom(beforeObject))
}
patch issues a patch for metadata and spec.
package patch
import (
	"context"
	"encoding/json"
	"reflect"
	"github.com/pkg/errors"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/runtime"
	"sigs.k8s.io/controller-runtime/pkg/client"
)
type Helper struct {
	client       client.Client
	beforeObject runtime.Object
	before       *unstructured.Unstructured
	after        *unstructured.Unstructured
	changes      map[string]bool
}
func NewHelper(obj runtime.Object, crClient client.Client) (*Helper, error) {
	if obj == nil || (reflect.ValueOf(obj).IsValid() && reflect.ValueOf(obj).IsNil()) {
		return nil, errors.Errorf("expected non-nil object")
	}
	unstructuredObj, err := toUnstructured(obj)
	if err != nil {
		return nil, err
	}
	return &Helper{
		client:       crClient,
		before:       unstructuredObj,
		beforeObject: obj.DeepCopyObject(),
	}, nil
}
func (h *Helper) Patch(ctx context.Context, obj runtime.Object) error {
	if obj == nil {
		return errors.Errorf("expected non-nil object")
	}
	var err error
	h.after, err = toUnstructured(obj)
	if err != nil {
		return err
	}
	h.changes, err = h.calculateChanges(obj)
	if err != nil {
		return err
	}
	if err := h.patch(ctx, obj); err != nil {
		return err
	}
	if err := h.patchStatus(ctx, obj); err != nil {
		return err
	}
	return nil
}