diff --git a/pkg/agent/controller/endpoint_slice.go b/pkg/agent/controller/endpoint_slice.go index 67cb1ba0e..afd0a9125 100644 --- a/pkg/agent/controller/endpoint_slice.go +++ b/pkg/agent/controller/endpoint_slice.go @@ -99,16 +99,14 @@ func (c *EndpointSliceController) start(stopCh <-chan struct{}) error { func (c *EndpointSliceController) onLocalEndpointSlice(obj runtime.Object, _ int, op syncer.Operation) (runtime.Object, bool) { endpointSlice := obj.(*discovery.EndpointSlice) - labels := endpointSlice.GetObjectMeta().GetLabels() - oldName := labels[mcsv1a1.LabelServiceName] + "-" + labels[constants.MCSLabelSourceCluster] - if op != syncer.Delete && endpointSlice.Name == oldName { - logger.Infof("EndpointSlice %s/%s has the old naming convention sans namespace - deleting it", + if op != syncer.Delete && isLegacyEndpointSlice(endpointSlice) { + logger.Infof("Found legacy EndpointSlice %s/%s - deleting it", endpointSlice.Namespace, endpointSlice.Name) err := c.syncer.GetLocalFederator().Delete(endpointSlice) if err != nil { - logger.Errorf(err, "Error deleting local EndpointSlice %s/%s", endpointSlice.Namespace, endpointSlice.Name) + logger.Errorf(err, "Error deleting legacy EndpointSlice %s/%s", endpointSlice.Namespace, endpointSlice.Name) } return nil, false @@ -117,6 +115,22 @@ func (c *EndpointSliceController) onLocalEndpointSlice(obj runtime.Object, _ int return obj, false } +func isLegacyEndpointSlice(endpointSlice *discovery.EndpointSlice) bool { + // The original name sans namespace prior to 0.15. + origName := endpointSlice.Labels[mcsv1a1.LabelServiceName] + "-" + endpointSlice.Labels[constants.MCSLabelSourceCluster] + if endpointSlice.Name == origName { + return true + } + + // Check for headless EndpointSlice derived from service Endpoints prior to 0.16. + if endpointSlice.Labels[constants.LabelIsHeadless] == strconv.FormatBool(true) && + strings.HasPrefix(endpointSlice.Name, endpointSlice.Labels[mcsv1a1.LabelServiceName]+"-"+endpointSlice.Namespace) { + return true + } + + return false +} + func (c *EndpointSliceController) onRemoteEndpointSlice(obj runtime.Object, _ int, _ syncer.Operation) (runtime.Object, bool) { endpointSlice := obj.(*discovery.EndpointSlice) endpointSlice.Namespace = endpointSlice.GetObjectMeta().GetLabels()[constants.LabelSourceNamespace] diff --git a/pkg/agent/controller/reconciliation_test.go b/pkg/agent/controller/reconciliation_test.go index 9842ec835..03ba5cdff 100644 --- a/pkg/agent/controller/reconciliation_test.go +++ b/pkg/agent/controller/reconciliation_test.go @@ -20,6 +20,8 @@ package controller_test import ( "context" + "fmt" + "strconv" "strings" . "github.com/onsi/ginkgo/v2" @@ -229,6 +231,22 @@ var _ = Describe("Reconciliation", func() { t.cluster1.service.Name, t.cluster1.clusterID) }) }) +}) + +var _ = Describe("EndpointSlice migration", func() { + var t *testDriver + + BeforeEach(func() { + t = newTestDiver() + }) + + JustBeforeEach(func() { + t.justBeforeEach() + }) + + AfterEach(func() { + t.afterEach() + }) When("a local EndpointSlice with the old naming convention sans namespace exists on startup", func() { epsName := "nginx-" + clusterID1 @@ -257,4 +275,33 @@ var _ = Describe("Reconciliation", func() { test.AwaitNoResource(t.brokerEndpointSliceClient, epsName) }) }) + + When("a legacy local EndpointSlice derived from Endpoints exists on startup", func() { + epsName := fmt.Sprintf("nginx-%s-%s", serviceNamespace, clusterID1) + + JustBeforeEach(func() { + eps := &discovery.EndpointSlice{ + ObjectMeta: metav1.ObjectMeta{ + Name: epsName, + Namespace: serviceNamespace, + Labels: map[string]string{ + discovery.LabelManagedBy: constants.LabelValueManagedBy, + constants.MCSLabelSourceCluster: clusterID1, + mcsv1a1.LabelServiceName: "nginx", + constants.LabelIsHeadless: strconv.FormatBool(true), + }, + }, + } + + test.CreateResource(t.cluster1.localEndpointSliceClient, eps) + + eps.Namespace = test.RemoteNamespace + test.CreateResource(t.brokerEndpointSliceClient, test.SetClusterIDLabel(eps, clusterID1)) + }) + + It("should delete it", func() { + test.AwaitNoResource(t.cluster1.localEndpointSliceClient, epsName) + test.AwaitNoResource(t.brokerEndpointSliceClient, epsName) + }) + }) })