func (a *APIPatchingApplicator) Apply(ctx context.Context, o client.Object, ao ...ApplyOption) error {
	m, ok := o.(metav1.Object)
	if !ok {
		return errors.New("cannot access object metadata")
	}
	if m.GetName() == "" && m.GetGenerateName() != "" {
		return errors.Wrap(a.client.Create(ctx, o), "cannot create object")
	}
	desired := o.DeepCopyObject()
	err := a.client.Get(ctx, types.NamespacedName{Name: m.GetName(), Namespace: m.GetNamespace()}, o)
	if kerrors.IsNotFound(err) {
		return errors.Wrap(a.client.Create(ctx, o), "cannot create object")
	}
	if err != nil {
		return errors.Wrap(err, "cannot get object")
	}
	for _, fn := range ao {
		if err := fn(ctx, o, desired); err != nil {
			return err
		}
	}
	return errors.Wrap(a.client.Patch(ctx, o, &patch{desired}), "cannot patch object")
}
Apply changes to the supplied object. The object will be created if it does
not exist, or patched if it does. If the object does exist, it will only be
patched if the passed object has the same or an empty resource version.
package resource
import (
	"context"
	"encoding/json"
	corev1 "k8s.io/api/core/v1"
	kerrors "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/types"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"github.com/crossplane/crossplane-runtime/pkg/errors"
	"github.com/crossplane/crossplane-runtime/pkg/meta"
)
const (
	errGetSecret            = "cannot get managed resource's connection secret"
	errSecretConflict       = "cannot establish control of existing connection secret"
	errUpdateSecret         = "cannot update connection secret"
	errCreateOrUpdateSecret = "cannot create or update connection secret"
	errUpdateObject = "cannot update object"
)
type APIManagedConnectionPropagator struct {
	Propagator ConnectionPropagator
}
func (a *APIManagedConnectionPropagator) PropagateConnection(ctx context.Context, to LocalConnectionSecretOwner, mg Managed) error {
	return a.Propagator.PropagateConnection(ctx, to, mg)
}
type APIConnectionPropagator struct {
	client ClientApplicator
	typer  runtime.ObjectTyper
}
func NewAPIConnectionPropagator(c client.Client, t runtime.ObjectTyper) *APIConnectionPropagator {
	return &APIConnectionPropagator{
		client: ClientApplicator{Client: c, Applicator: NewAPIUpdatingApplicator(c)},
		typer:  t,
	}
}
func (a *APIConnectionPropagator) PropagateConnection(ctx context.Context, to LocalConnectionSecretOwner, from ConnectionSecretOwner) error {
	if from.GetWriteConnectionSecretToReference() == nil || to.GetWriteConnectionSecretToReference() == nil {
		return nil
	}
	n := types.NamespacedName{
		Namespace: from.GetWriteConnectionSecretToReference().Namespace,
		Name:      from.GetWriteConnectionSecretToReference().Name,
	}
	fs := &corev1.Secret{}
	if err := a.client.Get(ctx, n, fs); err != nil {
		return errors.Wrap(err, errGetSecret)
	}
	if c := metav1.GetControllerOf(fs); c == nil || c.UID != from.GetUID() {
		return errors.New(errSecretConflict)
	}
	ts := LocalConnectionSecretFor(to, MustGetKind(to, a.typer))
	ts.Data = fs.Data
	meta.AllowPropagation(fs, ts)
	if err := a.client.Apply(ctx, ts, ConnectionSecretMustBeControllableBy(to.GetUID())); err != nil {
		return errors.Wrap(err, errCreateOrUpdateSecret)
	}
	return errors.Wrap(a.client.Update(ctx, fs), errUpdateSecret)
}
type APIPatchingApplicator struct {
	client client.Client
}
func NewAPIPatchingApplicator(c client.Client) *APIPatchingApplicator {
	return &APIPatchingApplicator{client: c}
}