diff --git a/docs/book/src/developer/providers/migrations/v1.5-to-v1.6.md b/docs/book/src/developer/providers/migrations/v1.5-to-v1.6.md index 8657e286a642..74d31ad99546 100644 --- a/docs/book/src/developer/providers/migrations/v1.5-to-v1.6.md +++ b/docs/book/src/developer/providers/migrations/v1.5-to-v1.6.md @@ -18,7 +18,8 @@ maintainers of providers and consumers of our Go API. ## Changes by Kind ### Deprecation - +- The function `sigs.k8s.io/cluster-api/addons/api/v1beta1` `DeleteBinding` has been deprecated. Please use `RemoveBinding` from the same package instead. +- ### Removals - API version `v1alpha4` is not served in v1.6 (users can enable it manually in case they are lagging behind with deprecation cycles). Important: `v1alpha4` will be completely removed in 1.7. diff --git a/exp/addons/api/v1beta1/clusterresourcesetbinding_types.go b/exp/addons/api/v1beta1/clusterresourcesetbinding_types.go index 299112258a55..37591da520cd 100644 --- a/exp/addons/api/v1beta1/clusterresourcesetbinding_types.go +++ b/exp/addons/api/v1beta1/clusterresourcesetbinding_types.go @@ -20,8 +20,7 @@ import ( "reflect" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "sigs.k8s.io/cluster-api/util" + "k8s.io/apimachinery/pkg/runtime/schema" ) // ANCHOR: ResourceBinding @@ -97,7 +96,20 @@ func (c *ClusterResourceSetBinding) GetOrCreateBinding(clusterResourceSet *Clust return binding } +// RemoveBinding removes the ClusterResourceSet from the ClusterResourceSetBinding Bindings list. +func (c *ClusterResourceSetBinding) RemoveBinding(clusterResourceSet *ClusterResourceSet) { + for i, binding := range c.Spec.Bindings { + if binding.ClusterResourceSetName == clusterResourceSet.Name { + copy(c.Spec.Bindings[i:], c.Spec.Bindings[i+1:]) + c.Spec.Bindings = c.Spec.Bindings[:len(c.Spec.Bindings)-1] + break + } + } +} + // DeleteBinding removes the ClusterResourceSet from the ClusterResourceSetBinding Bindings list. +// +// Deprecated: This function is deprecated and will be removed in an upcoming release of Cluster API. func (c *ClusterResourceSetBinding) DeleteBinding(clusterResourceSet *ClusterResourceSet) { for i, binding := range c.Spec.Bindings { if binding.ClusterResourceSetName == clusterResourceSet.Name { @@ -106,13 +118,53 @@ func (c *ClusterResourceSetBinding) DeleteBinding(clusterResourceSet *ClusterRes break } } - c.OwnerReferences = util.RemoveOwnerRef(c.GetOwnerReferences(), metav1.OwnerReference{ + c.OwnerReferences = removeOwnerRef(c.GetOwnerReferences(), metav1.OwnerReference{ APIVersion: clusterResourceSet.APIVersion, Kind: clusterResourceSet.Kind, Name: clusterResourceSet.Name, }) } +// removeOwnerRef returns the slice of owner references after removing the supplied owner ref. +// Note: removeOwnerRef ignores apiVersion and UID. It will remove the passed ownerReference where it matches Name, Group and Kind. +// +// Deprecated: This function is deprecated and will be removed in an upcoming release of Cluster API. +func removeOwnerRef(ownerReferences []metav1.OwnerReference, inputRef metav1.OwnerReference) []metav1.OwnerReference { + if index := indexOwnerRef(ownerReferences, inputRef); index != -1 { + return append(ownerReferences[:index], ownerReferences[index+1:]...) + } + return ownerReferences +} + +// indexOwnerRef returns the index of the owner reference in the slice if found, or -1. +// +// Deprecated: This function is deprecated and will be removed in an upcoming release of Cluster API. +func indexOwnerRef(ownerReferences []metav1.OwnerReference, ref metav1.OwnerReference) int { + for index, r := range ownerReferences { + if referSameObject(r, ref) { + return index + } + } + return -1 +} + +// Returns true if a and b point to the same object based on Group, Kind and Name. +// +// Deprecated: This function is deprecated and will be removed in an upcoming release of Cluster API. +func referSameObject(a, b metav1.OwnerReference) bool { + aGV, err := schema.ParseGroupVersion(a.APIVersion) + if err != nil { + return false + } + + bGV, err := schema.ParseGroupVersion(b.APIVersion) + if err != nil { + return false + } + + return aGV.Group == bGV.Group && a.Kind == b.Kind && a.Name == b.Name +} + // +kubebuilder:object:root=true // +kubebuilder:resource:path=clusterresourcesetbindings,scope=Namespaced,categories=cluster-api // +kubebuilder:subresource:status diff --git a/exp/addons/internal/controllers/clusterresourceset_controller.go b/exp/addons/internal/controllers/clusterresourceset_controller.go index 3c451d5b6c6b..3e30f5d75c9a 100644 --- a/exp/addons/internal/controllers/clusterresourceset_controller.go +++ b/exp/addons/internal/controllers/clusterresourceset_controller.go @@ -196,7 +196,12 @@ func (r *ClusterResourceSetReconciler) reconcileDelete(ctx context.Context, clus return err } - clusterResourceSetBinding.DeleteBinding(crs) + clusterResourceSetBinding.RemoveBinding(crs) + clusterResourceSetBinding.OwnerReferences = util.RemoveOwnerRef(clusterResourceSetBinding.GetOwnerReferences(), metav1.OwnerReference{ + APIVersion: crs.APIVersion, + Kind: crs.Kind, + Name: crs.Name, + }) // If CRS list is empty in the binding, delete the binding else // attempt to Patch the ClusterResourceSetBinding object after delete reconciliation if there is at least 1 binding left.