func AnnotationKeyPropagateTo(o metav1.Object) string {
	h := fnv.New32a()
	h.Write([]byte(o.GetNamespace()))  
	h.Write([]byte(o.GetName()))       
	return fmt.Sprintf("%s%x", AnnotationKeyPropagateToPrefix, h.Sum32())
}
AnnotationKeyPropagateTo returns an annotation key whose presence indicates
that the annotated object consents to propagation from the supplied object.
The annotation name (which follows the prefix) can be anything that doesn't
collide with another annotation. to.propagation.crossplane.io/example would
be valid. This function uses a hash of the supplied object's namespace and
name in order to avoid collisions and keep the suffix relatively short.
package meta
import (
	"fmt"
	"hash/fnv"
	"strings"
	"time"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/apimachinery/pkg/types"
	xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
	"github.com/crossplane/crossplane-runtime/pkg/errors"
)
const (
	AnnotationKeyExternalName = "crossplane.io/external-name"
	AnnotationKeyExternalCreatePending = "crossplane.io/external-create-pending"
	AnnotationKeyExternalCreateSucceeded = "crossplane.io/external-create-succeeded"
	AnnotationKeyExternalCreateFailed = "crossplane.io/external-create-failed"
)
const (
	AnnotationKeyPropagateToPrefix = "to.propagate.crossplane.io/"
	AnnotationKeyPropagateFromNamespace = "from.propagate.crossplane.io/namespace"
	AnnotationKeyPropagateFromName      = "from.propagate.crossplane.io/name"
)
func ReferenceTo(o metav1.Object, of schema.GroupVersionKind) *corev1.ObjectReference {
	v, k := of.ToAPIVersionAndKind()
	return &corev1.ObjectReference{
		APIVersion: v,
		Kind:       k,
		Namespace:  o.GetNamespace(),
		Name:       o.GetName(),
		UID:        o.GetUID(),
	}
}
func TypedReferenceTo(o metav1.Object, of schema.GroupVersionKind) *xpv1.TypedReference {
	v, k := of.ToAPIVersionAndKind()
	return &xpv1.TypedReference{
		APIVersion: v,
		Kind:       k,
		Name:       o.GetName(),
		UID:        o.GetUID(),
	}
}
func AsOwner(r *xpv1.TypedReference) metav1.OwnerReference {
	return metav1.OwnerReference{
		APIVersion: r.APIVersion,
		Kind:       r.Kind,
		Name:       r.Name,
		UID:        r.UID,
	}
}
func AsController(r *xpv1.TypedReference) metav1.OwnerReference {
	c := true
	ref := AsOwner(r)
	ref.Controller = &c
	return ref
}
func HaveSameController(a, b metav1.Object) bool {
	ac := metav1.GetControllerOf(a)
	bc := metav1.GetControllerOf(b)
	if ac == nil || bc == nil {
		return false
	}
	return ac.UID == bc.UID
}
func NamespacedNameOf(r *corev1.ObjectReference) types.NamespacedName {
	return types.NamespacedName{Namespace: r.Namespace, Name: r.Name}
}
func AddOwnerReference(o metav1.Object, r metav1.OwnerReference) {
	refs := o.GetOwnerReferences()
	for i := range refs {
		if refs[i].UID == r.UID {
			refs[i] = r
			o.SetOwnerReferences(refs)
			return
		}
	}
	o.SetOwnerReferences(append(refs, r))
}
func AddControllerReference(o metav1.Object, r metav1.OwnerReference) error {
	if c := metav1.GetControllerOf(o); c != nil && c.UID != r.UID {
		return errors.Errorf("%s is already controlled by %s %s (UID %s)", o.GetName(), c.Kind, c.Name, c.UID)
	}
	AddOwnerReference(o, r)
	return nil
}
func AddFinalizer(o metav1.Object, finalizer string) {
	f := o.GetFinalizers()
	for _, e := range f {
		if e == finalizer {
			return
		}
	}
	o.SetFinalizers(append(f, finalizer))
}
func RemoveFinalizer(o metav1.Object, finalizer string) {
	f := o.GetFinalizers()
	for i, e := range f {
		if e == finalizer {
			f = append(f[:i], f[i+1:]...)
		}
	}
	o.SetFinalizers(f)
}
func FinalizerExists(o metav1.Object, finalizer string) bool {
	f := o.GetFinalizers()
	for _, e := range f {
		if e == finalizer {
			return true
		}
	}
	return false
}
func AddLabels(o metav1.Object, labels map[string]string) {
	l := o.GetLabels()
	if l == nil {
		o.SetLabels(labels)
		return
	}
	for k, v := range labels {
		l[k] = v
	}
	o.SetLabels(l)
}
func RemoveLabels(o metav1.Object, labels ...string) {
	l := o.GetLabels()
	if l == nil {
		return
	}
	for _, k := range labels {
		delete(l, k)
	}
	o.SetLabels(l)
}
func AddAnnotations(o metav1.Object, annotations map[string]string) {
	a := o.GetAnnotations()
	if a == nil {
		o.SetAnnotations(annotations)
		return
	}
	for k, v := range annotations {
		a[k] = v
	}
	o.SetAnnotations(a)
}
func RemoveAnnotations(o metav1.Object, annotations ...string) {
	a := o.GetAnnotations()
	if a == nil {
		return
	}
	for _, k := range annotations {
		delete(a, k)
	}
	o.SetAnnotations(a)
}
func WasDeleted(o metav1.Object) bool {
	return !o.GetDeletionTimestamp().IsZero()
}
func WasCreated(o metav1.Object) bool {
	t := o.GetCreationTimestamp()
	return !t.IsZero()
}
func GetExternalName(o metav1.Object) string {
	return o.GetAnnotations()[AnnotationKeyExternalName]
}
func SetExternalName(o metav1.Object, name string) {
	AddAnnotations(o, map[string]string{AnnotationKeyExternalName: name})
}
func GetExternalCreatePending(o metav1.Object) time.Time {
	a := o.GetAnnotations()[AnnotationKeyExternalCreatePending]
	t, err := time.Parse(time.RFC3339, a)
	if err != nil {
		return time.Time{}
	}
	return t
}
func SetExternalCreatePending(o metav1.Object, t time.Time) {
	AddAnnotations(o, map[string]string{AnnotationKeyExternalCreatePending: t.Format(time.RFC3339)})
}
func GetExternalCreateSucceeded(o metav1.Object) time.Time {
	a := o.GetAnnotations()[AnnotationKeyExternalCreateSucceeded]
	t, err := time.Parse(time.RFC3339, a)
	if err != nil {
		return time.Time{}
	}
	return t
}
func SetExternalCreateSucceeded(o metav1.Object, t time.Time) {
	AddAnnotations(o, map[string]string{AnnotationKeyExternalCreateSucceeded: t.Format(time.RFC3339)})
}
func GetExternalCreateFailed(o metav1.Object) time.Time {
	a := o.GetAnnotations()[AnnotationKeyExternalCreateFailed]
	t, err := time.Parse(time.RFC3339, a)
	if err != nil {
		return time.Time{}
	}
	return t
}
func SetExternalCreateFailed(o metav1.Object, t time.Time) {
	AddAnnotations(o, map[string]string{AnnotationKeyExternalCreateFailed: t.Format(time.RFC3339)})
}
func ExternalCreateIncomplete(o metav1.Object) bool {
	pending := GetExternalCreatePending(o)
	succeeded := GetExternalCreateSucceeded(o)
	failed := GetExternalCreateFailed(o)
	if pending.IsZero() {
		return false
	}
	latest := succeeded
	if failed.After(succeeded) {
		latest = failed
	}
	return pending.After(latest)
}
func ExternalCreateSucceededDuring(o metav1.Object, d time.Duration) bool {
	t := GetExternalCreateSucceeded(o)
	if t.IsZero() {
		return false
	}
	return time.Since(t) < d
}
func AllowPropagation(from, to metav1.Object) {
	AddAnnotations(to, map[string]string{
		AnnotationKeyPropagateFromNamespace: from.GetNamespace(),
		AnnotationKeyPropagateFromName:      from.GetName(),
	})
	AddAnnotations(from, map[string]string{
		AnnotationKeyPropagateTo(to): to.GetNamespace() + "/" + to.GetName(),
	})
}