@@ -19,22 +19,25 @@ import (
1919 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2020 "k8s.io/apimachinery/pkg/types"
2121 ctrl "sigs.k8s.io/controller-runtime"
22+ "sigs.k8s.io/controller-runtime/pkg/client"
2223 "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
2324 mcmanager "sigs.k8s.io/multicluster-runtime/pkg/manager"
2425
2526 securityv1alpha1 "github.com/platform-mesh/security-operator/api/v1alpha1"
2627)
2728
28- func NewAuthorizationModelGenerationSubroutine (mcMgr mcmanager.Manager ) * AuthorizationModelGenerationSubroutine {
29+ func NewAuthorizationModelGenerationSubroutine (mcMgr mcmanager.Manager , allClient client. Client ) * AuthorizationModelGenerationSubroutine {
2930 return & AuthorizationModelGenerationSubroutine {
30- mgr : mcMgr ,
31+ mgr : mcMgr ,
32+ allClient : allClient ,
3133 }
3234}
3335
3436var _ lifecyclesubroutine.Subroutine = & AuthorizationModelGenerationSubroutine {}
3537
3638type AuthorizationModelGenerationSubroutine struct {
37- mgr mcmanager.Manager
39+ mgr mcmanager.Manager
40+ allClient client.Client
3841}
3942
4043var modelTpl = template .Must (template .New ("model" ).Parse (`module {{ .Name }}
@@ -86,19 +89,19 @@ func (a *AuthorizationModelGenerationSubroutine) Finalize(ctx context.Context, i
8689
8790 bindingToDelete := instance .(* kcpv1alpha1.APIBinding )
8891
89- cluster , err := a .mgr .ClusterFromContext (ctx )
92+ bindingCluster , err := a .mgr .ClusterFromContext (ctx )
9093 if err != nil {
9194 return ctrl.Result {}, errors .NewOperatorError (fmt .Errorf ("unable to get cluster from context: %w" , err ), true , false )
9295 }
9396
9497 var bindings kcpv1alpha1.APIBindingList
95- err = cluster . GetClient () .List (ctx , & bindings )
98+ err = a . allClient .List (ctx , & bindings )
9699 if err != nil {
97100 return ctrl.Result {}, errors .NewOperatorError (err , true , true )
98101 }
99102
100103 var toDeleteAccountInfo accountv1alpha1.AccountInfo
101- err = cluster .GetClient ().Get (ctx , types.NamespacedName {Name : "account" }, & toDeleteAccountInfo )
104+ err = bindingCluster .GetClient ().Get (ctx , types.NamespacedName {Name : "account" }, & toDeleteAccountInfo )
102105 if err != nil {
103106 log .Error ().Err (err ).Msg ("unable to get account info for binding deletion" )
104107 return ctrl.Result {}, errors .NewOperatorError (err , true , true )
@@ -110,16 +113,16 @@ func (a *AuthorizationModelGenerationSubroutine) Finalize(ctx context.Context, i
110113 continue
111114 }
112115
113- bindingCluster , err := a .mgr .GetCluster (ctx , string (logicalcluster .From (& binding )))
116+ bindingWsCluster , err := a .mgr .GetCluster (ctx , string (logicalcluster .From (& binding )))
114117 if err != nil {
115118 return ctrl.Result {}, errors .NewOperatorError (err , true , true )
116119 }
117120
118121 var accountInfo accountv1alpha1.AccountInfo
119- err = bindingCluster .GetClient ().Get (ctx , types.NamespacedName {Name : "account" }, & accountInfo )
122+ err = bindingWsCluster .GetClient ().Get (ctx , types.NamespacedName {Name : "account" }, & accountInfo )
120123 if kerrors .IsNotFound (err ) || meta .IsNoMatchError (err ) {
121- // If the accountinfo does not exist, we can skip the model generation.
122- return ctrl. Result {}, nil
124+ // If the accountinfo does not exist, skip this binding and continue with others
125+ continue
123126 }
124127 if err != nil {
125128 return ctrl.Result {}, errors .NewOperatorError (err , true , true )
@@ -140,26 +143,52 @@ func (a *AuthorizationModelGenerationSubroutine) Finalize(ctx context.Context, i
140143 return ctrl.Result {}, nil
141144 }
142145
143- err = cluster .GetClient ().Delete (ctx , & securityv1alpha1.AuthorizationModel {
144- ObjectMeta : metav1.ObjectMeta {
145- Name : fmt .Sprintf ("%s-%s" , bindingToDelete .Spec .Reference .Export .Name , bindingToDelete .Spec .Reference .Export .Path ),
146- },
147- })
146+ apiExportCluster , err := a .mgr .GetCluster (ctx , bindingToDelete .Status .APIExportClusterName )
148147 if err != nil {
149- if kerrors .IsNotFound (err ) {
150- // If the model does not exist, we can skip the deletion.
151- return ctrl.Result {}, nil
152- }
148+ return ctrl.Result {}, errors .NewOperatorError (fmt .Errorf ("failed to get cluster %q: %w" , bindingToDelete .Status .APIExportClusterName , err ), true , false )
149+ }
150+ apiExportClient := apiExportCluster .GetClient ()
151+
152+ var apiExport kcpv1alpha1.APIExport
153+ err = apiExportClient .Get (ctx , types.NamespacedName {Name : bindingToDelete .Spec .Reference .Export .Name }, & apiExport )
154+ if err != nil {
155+ log .Error ().Err (err ).Msg ("failed to get apiexport for binding deletion" )
153156 return ctrl.Result {}, errors .NewOperatorError (err , true , true )
154157 }
155158
159+ for _ , latestResourceSchema := range apiExport .Spec .LatestResourceSchemas {
160+ var resourceSchema kcpv1alpha1.APIResourceSchema
161+ err := apiExportClient .Get (ctx , types.NamespacedName {Name : latestResourceSchema }, & resourceSchema )
162+ if err != nil {
163+ log .Error ().Err (err ).Msg ("failed to get resource schema for binding deletion" )
164+ return ctrl.Result {}, errors .NewOperatorError (err , true , true )
165+ }
166+
167+ authModelName := fmt .Sprintf ("%s-%s" , resourceSchema .Spec .Names .Plural , toDeleteAccountInfo .Spec .Organization .Name )
168+ err = apiExportClient .Delete (ctx , & securityv1alpha1.AuthorizationModel {
169+ ObjectMeta : metav1.ObjectMeta {
170+ Name : authModelName ,
171+ },
172+ })
173+ if err != nil {
174+ if kerrors .IsNotFound (err ) {
175+ // If the model does not exist, we can skip the deletion.
176+ log .Info ().Msg (fmt .Sprintf ("authorization model %s does not exist" , authModelName ))
177+ continue
178+ }
179+ log .Error ().Err (err ).Msg ("failed to delete authorization model" )
180+ return ctrl.Result {}, errors .NewOperatorError (err , true , true )
181+ }
182+ log .Info ().Msg (fmt .Sprintf ("authorization model %s has been deleted" , authModelName ))
183+ }
184+
156185 return ctrl.Result {}, nil
157186
158187}
159188
160189// Finalizers implements lifecycle.Subroutine.
161190func (a * AuthorizationModelGenerationSubroutine ) Finalizers (_ lifecyclecontrollerruntime.RuntimeObject ) []string {
162- return []string {}
191+ return []string {"core.platform-mesh.io/apibinding-finalizer" }
163192}
164193
165194// GetName implements lifecycle.Subroutine.
0 commit comments