From ccc309a9fce3811544735926c31d54f32bfe244a Mon Sep 17 00:00:00 2001 From: OlegErshov Date: Fri, 30 Jan 2026 13:02:29 +0100 Subject: [PATCH 1/5] fix: updated condition on core.platform-mesh.io api export On-behalf-of: SAP aleh.yarshou@sap.com --- internal/subroutine/authorization_model_generation.go | 7 ++++--- internal/subroutine/authorization_model_generation_test.go | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/internal/subroutine/authorization_model_generation.go b/internal/subroutine/authorization_model_generation.go index 87423faf..67487fb2 100644 --- a/internal/subroutine/authorization_model_generation.go +++ b/internal/subroutine/authorization_model_generation.go @@ -28,7 +28,8 @@ import ( ) const ( - apiBindingFinalizer = "core.platform-mesh.io/apibinding-finalizer" + apiBindingFinalizer = "core.platform-mesh.io/apibinding-finalizer" + corePlatformMeshApiExport = "core.platform-mesh.io" ) func NewAuthorizationModelGenerationSubroutine(mcMgr mcmanager.Manager, allClient client.Client) *AuthorizationModelGenerationSubroutine { @@ -194,7 +195,7 @@ func (a *AuthorizationModelGenerationSubroutine) Finalize(ctx context.Context, i // Finalizers implements lifecycle.Subroutine. func (a *AuthorizationModelGenerationSubroutine) Finalizers(instance lifecyclecontrollerruntime.RuntimeObject) []string { binding := instance.(*kcpapisv1alpha1.APIBinding) - if strings.Contains(binding.Name, "platform-mesh.io") || strings.Contains(binding.Name, "kcp.io") { + if binding.Spec.Reference.Export.Name == corePlatformMeshApiExport || strings.HasSuffix(binding.Spec.Reference.Export.Name, "kcp.io") { return []string{} } return []string{apiBindingFinalizer} @@ -224,7 +225,7 @@ func (a *AuthorizationModelGenerationSubroutine) Process(ctx context.Context, in return ctrl.Result{}, errors.NewOperatorError(err, true, true) } - if binding.Spec.Reference.Export.Name == "core.platform-mesh.io" || strings.HasSuffix(binding.Spec.Reference.Export.Name, "kcp.io") { + if binding.Spec.Reference.Export.Name == corePlatformMeshApiExport || strings.HasSuffix(binding.Spec.Reference.Export.Name, "kcp.io") { // If the APIExport is the core.platform-mesh.io, we can skip the model generation. return ctrl.Result{}, nil } diff --git a/internal/subroutine/authorization_model_generation_test.go b/internal/subroutine/authorization_model_generation_test.go index 0dcb7772..eb868a4e 100644 --- a/internal/subroutine/authorization_model_generation_test.go +++ b/internal/subroutine/authorization_model_generation_test.go @@ -934,7 +934,7 @@ func TestAuthorizationModelGeneration_Finalizers(t *testing.T) { expectFinalizer: true, }, { - name: "returns no finalizer when name contains platform-mesh.io", + name: "returns no finalizer when name contains core.platform-mesh.io", bindingName: "core.platform-mesh.io-awuzd", expectFinalizer: false, }, @@ -949,9 +949,9 @@ func TestAuthorizationModelGeneration_Finalizers(t *testing.T) { expectFinalizer: false, }, { - name: "returns no finalizer when name contains platform-mesh.io in the middle", + name: "returns finalizer when name contains platform-mesh.io in the middle", bindingName: "something.platform-mesh.io-suffix", - expectFinalizer: false, + expectFinalizer: true, }, } for _, tt := range tests { From 65a48646fe2d6fc77025855cb2f9df461fa7de54 Mon Sep 17 00:00:00 2001 From: OlegErshov Date: Fri, 30 Jan 2026 13:07:28 +0100 Subject: [PATCH 2/5] updated tests On-behalf-of: SAP aleh.yarshou@sap.com --- .../authorization_model_generation_test.go | 37 ++++++++++++------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/internal/subroutine/authorization_model_generation_test.go b/internal/subroutine/authorization_model_generation_test.go index eb868a4e..839bbe1f 100644 --- a/internal/subroutine/authorization_model_generation_test.go +++ b/internal/subroutine/authorization_model_generation_test.go @@ -924,40 +924,49 @@ func TestAuthorizationModelGeneration_Finalizers(t *testing.T) { sub := subroutine.NewAuthorizationModelGenerationSubroutine(nil, mocks.NewMockClient(t)) tests := []struct { - name string - bindingName string + name string + exportName string expectFinalizer bool }{ { - name: "returns finalizer when name has neither platform-mesh.io nor kcp.io", - bindingName: "my-binding", + name: "returns finalizer when export name is neither core.platform-mesh.io nor suffix kcp.io", + exportName: "my-export", expectFinalizer: true, }, { - name: "returns no finalizer when name contains core.platform-mesh.io", - bindingName: "core.platform-mesh.io-awuzd", + name: "returns finalizer when export name is foo", + exportName: "foo", + expectFinalizer: true, + }, + { + name: "returns no finalizer when export name equals core.platform-mesh.io", + exportName: "core.platform-mesh.io", + expectFinalizer: false, + }, + { + name: "returns no finalizer when export name has suffix kcp.io", + exportName: "tenancy.kcp.io", expectFinalizer: false, }, { - name: "returns no finalizer when name contains kcp.io", - bindingName: "tenancy.kcp.io-dr0q1", + name: "returns no finalizer when export name is topology.kcp.io", + exportName: "topology.kcp.io", expectFinalizer: false, }, { - name: "returns no finalizer when name contains topology.kcp.io", - bindingName: "topology.kcp.io-5oxoy", + name: "returns no finalizer when export name has suffix kcp.io (apis.kcp.io)", + exportName: "apis.kcp.io", expectFinalizer: false, }, { - name: "returns finalizer when name contains platform-mesh.io in the middle", - bindingName: "something.platform-mesh.io-suffix", + name: "returns finalizer when export name is not exact core.platform-mesh.io", + exportName: "something.platform-mesh.io", expectFinalizer: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - binding := newApiBinding("foo", "bar") - binding.Name = tt.bindingName + binding := newApiBinding(tt.exportName, "root") got := sub.Finalizers(binding) if tt.expectFinalizer { assert.Equal(t, []string{"core.platform-mesh.io/apibinding-finalizer"}, got) From 82b46701e1d635b95ad3e9d460828de2906611b2 Mon Sep 17 00:00:00 2001 From: OlegErshov Date: Fri, 30 Jan 2026 13:09:23 +0100 Subject: [PATCH 3/5] chore: refactored tests On-behalf-of: SAP aleh.yarshou@sap.com --- .../authorization_model_generation_test.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/internal/subroutine/authorization_model_generation_test.go b/internal/subroutine/authorization_model_generation_test.go index 839bbe1f..5d6e0227 100644 --- a/internal/subroutine/authorization_model_generation_test.go +++ b/internal/subroutine/authorization_model_generation_test.go @@ -933,11 +933,6 @@ func TestAuthorizationModelGeneration_Finalizers(t *testing.T) { exportName: "my-export", expectFinalizer: true, }, - { - name: "returns finalizer when export name is foo", - exportName: "foo", - expectFinalizer: true, - }, { name: "returns no finalizer when export name equals core.platform-mesh.io", exportName: "core.platform-mesh.io", @@ -948,16 +943,6 @@ func TestAuthorizationModelGeneration_Finalizers(t *testing.T) { exportName: "tenancy.kcp.io", expectFinalizer: false, }, - { - name: "returns no finalizer when export name is topology.kcp.io", - exportName: "topology.kcp.io", - expectFinalizer: false, - }, - { - name: "returns no finalizer when export name has suffix kcp.io (apis.kcp.io)", - exportName: "apis.kcp.io", - expectFinalizer: false, - }, { name: "returns finalizer when export name is not exact core.platform-mesh.io", exportName: "something.platform-mesh.io", From 270c8bbdea6443a048893bdd97c545ab24723f10 Mon Sep 17 00:00:00 2001 From: OlegErshov Date: Fri, 30 Jan 2026 17:16:26 +0100 Subject: [PATCH 4/5] fix: removed platform-mesh.io check in apibinding finalizers On-behalf-of: SAP aleh.yarshou@sap.com --- .../authorization_model_generation.go | 2 +- .../authorization_model_generation_test.go | 26 ++++++++++++------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/internal/subroutine/authorization_model_generation.go b/internal/subroutine/authorization_model_generation.go index 67487fb2..3ca6ae15 100644 --- a/internal/subroutine/authorization_model_generation.go +++ b/internal/subroutine/authorization_model_generation.go @@ -195,7 +195,7 @@ func (a *AuthorizationModelGenerationSubroutine) Finalize(ctx context.Context, i // Finalizers implements lifecycle.Subroutine. func (a *AuthorizationModelGenerationSubroutine) Finalizers(instance lifecyclecontrollerruntime.RuntimeObject) []string { binding := instance.(*kcpapisv1alpha1.APIBinding) - if binding.Spec.Reference.Export.Name == corePlatformMeshApiExport || strings.HasSuffix(binding.Spec.Reference.Export.Name, "kcp.io") { + if strings.Contains(binding.Name, "kcp.io") { return []string{} } return []string{apiBindingFinalizer} diff --git a/internal/subroutine/authorization_model_generation_test.go b/internal/subroutine/authorization_model_generation_test.go index 5d6e0227..e8273a9d 100644 --- a/internal/subroutine/authorization_model_generation_test.go +++ b/internal/subroutine/authorization_model_generation_test.go @@ -925,33 +925,39 @@ func TestAuthorizationModelGeneration_Finalizers(t *testing.T) { tests := []struct { name string - exportName string + bindingName string expectFinalizer bool }{ { - name: "returns finalizer when export name is neither core.platform-mesh.io nor suffix kcp.io", - exportName: "my-export", + name: "returns finalizer when binding name is core.platform-mesh.io", + bindingName: "core.platform-mesh.io", expectFinalizer: true, }, { - name: "returns no finalizer when export name equals core.platform-mesh.io", - exportName: "core.platform-mesh.io", + name: "returns no finalizer when binding name contains kcp.io", + bindingName: "tenancy.kcp.io", expectFinalizer: false, }, { - name: "returns no finalizer when export name has suffix kcp.io", - exportName: "tenancy.kcp.io", + name: "returns no finalizer when binding name is topology.kcp.io", + bindingName: "topology.kcp.io", expectFinalizer: false, }, { - name: "returns finalizer when export name is not exact core.platform-mesh.io", - exportName: "something.platform-mesh.io", + name: "returns no finalizer when binding name is apis.kcp.io", + bindingName: "apis.kcp.io", + expectFinalizer: false, + }, + { + name: "returns finalizer when binding name contains platform-mesh.io but not kcp.io", + bindingName: "something.platform-mesh.io", expectFinalizer: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - binding := newApiBinding(tt.exportName, "root") + binding := newApiBinding("export", "root:orgs:test") + binding.Name = tt.bindingName got := sub.Finalizers(binding) if tt.expectFinalizer { assert.Equal(t, []string{"core.platform-mesh.io/apibinding-finalizer"}, got) From 335fd52d02cb9387aab75868da2bc5314b32fbbe Mon Sep 17 00:00:00 2001 From: OlegErshov Date: Tue, 3 Feb 2026 11:26:27 +0100 Subject: [PATCH 5/5] little refactoring On-behalf-of: SAP aleh.yarshou@sap.com --- .../authorization_model_generation.go | 2 +- .../authorization_model_generation_test.go | 25 +++++++++---------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/internal/subroutine/authorization_model_generation.go b/internal/subroutine/authorization_model_generation.go index 8b147b60..b6532ebf 100644 --- a/internal/subroutine/authorization_model_generation.go +++ b/internal/subroutine/authorization_model_generation.go @@ -196,7 +196,7 @@ func (a *AuthorizationModelGenerationSubroutine) Finalize(ctx context.Context, i // Finalizers implements lifecycle.Subroutine. func (a *AuthorizationModelGenerationSubroutine) Finalizers(instance lifecyclecontrollerruntime.RuntimeObject) []string { binding := instance.(*kcpapisv1alpha2.APIBinding) - if strings.Contains(binding.Name, "kcp.io") { + if strings.HasSuffix(binding.Spec.Reference.Export.Name, "kcp.io") { return []string{} } return []string{apiBindingFinalizer} diff --git a/internal/subroutine/authorization_model_generation_test.go b/internal/subroutine/authorization_model_generation_test.go index 09c34abc..62264b34 100644 --- a/internal/subroutine/authorization_model_generation_test.go +++ b/internal/subroutine/authorization_model_generation_test.go @@ -927,39 +927,38 @@ func TestAuthorizationModelGeneration_Finalizers(t *testing.T) { tests := []struct { name string - bindingName string + exportName string expectFinalizer bool }{ { - name: "returns finalizer when binding name is core.platform-mesh.io", - bindingName: "core.platform-mesh.io", + name: "returns finalizer when export name is core.platform-mesh.io", + exportName: "core.platform-mesh.io", expectFinalizer: true, }, { - name: "returns no finalizer when binding name contains kcp.io", - bindingName: "tenancy.kcp.io", + name: "returns no finalizer when export name has suffix kcp.io", + exportName: "tenancy.kcp.io", expectFinalizer: false, }, { - name: "returns no finalizer when binding name is topology.kcp.io", - bindingName: "topology.kcp.io", + name: "returns no finalizer when export name is topology.kcp.io", + exportName: "topology.kcp.io", expectFinalizer: false, }, { - name: "returns no finalizer when binding name is apis.kcp.io", - bindingName: "apis.kcp.io", + name: "returns no finalizer when export name is apis.kcp.io", + exportName: "apis.kcp.io", expectFinalizer: false, }, { - name: "returns finalizer when binding name contains platform-mesh.io but not kcp.io", - bindingName: "something.platform-mesh.io", + name: "returns finalizer when export name has suffix platform-mesh.io but not kcp.io", + exportName: "something.platform-mesh.io", expectFinalizer: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - binding := newApiBinding("export", "root:orgs:test") - binding.Name = tt.bindingName + binding := newApiBinding(tt.exportName, "root:orgs:test") got := sub.Finalizers(binding) if tt.expectFinalizer { assert.Equal(t, []string{"core.platform-mesh.io/apibinding-finalizer"}, got)