diff --git a/pkg/controllers/namespacesync/copy.go b/pkg/controllers/namespacesync/copy.go index 5e8767441..51532f479 100644 --- a/pkg/controllers/namespacesync/copy.go +++ b/pkg/controllers/namespacesync/copy.go @@ -8,6 +8,7 @@ import ( "fmt" corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -19,9 +20,7 @@ func copyClusterClassAndTemplates( source *clusterv1.ClusterClass, namespace string, ) error { - target := source.DeepCopy() - target.SetNamespace(namespace) - target.SetResourceVersion("") + target := copyObjectForCreate(source, source.Name, namespace) if err := walkReferences(ctx, target, func(ctx context.Context, ref *corev1.ObjectReference) error { // Get referenced Template @@ -31,9 +30,7 @@ func copyClusterClassAndTemplates( } // Copy Template to target namespace - targetTemplate := sourceTemplate.DeepCopy() - targetTemplate.SetNamespace(namespace) - targetTemplate.SetResourceVersion("") + targetTemplate := copyObjectForCreate(sourceTemplate, sourceTemplate.GetName(), namespace) if err := w.Create(ctx, targetTemplate); err != nil { return fmt.Errorf( @@ -63,3 +60,34 @@ func copyClusterClassAndTemplates( } return nil } + +// copyObjectForCreate copies the object, updating the name and namespace, +// and preserving only labels and annotations metadata. +func copyObjectForCreate[T client.Object](src T, name, namespace string) T { + dst := src.DeepCopyObject().(T) + + dst.SetName(name) + dst.SetNamespace(namespace) + + // Zero out ManagedFields (clients will set them) + dst.SetManagedFields(nil) + // Zero out OwnerReferences (object is garbage-collected if + // owners are not in the target namespace) + dst.SetOwnerReferences(nil) + + // Zero out fields that are ignored by the API server on create + dst.SetCreationTimestamp(metav1.Time{}) + dst.SetDeletionGracePeriodSeconds(nil) + dst.SetDeletionTimestamp(nil) + dst.SetFinalizers(nil) + dst.SetGenerateName("") + dst.SetGeneration(0) + dst.SetLabels(nil) + dst.SetManagedFields(nil) + dst.SetOwnerReferences(nil) + dst.SetResourceVersion("") + dst.SetSelfLink("") + dst.SetUID("") + + return dst +}