33import io .fabric8 .kubernetes .api .model .Secret ;
44import io .fabric8 .kubernetes .client .KubernetesClient ;
55import io .javaoperatorsdk .operator .api .config .informer .InformerEventSourceConfiguration ;
6+ import io .javaoperatorsdk .operator .api .reconciler .Cleaner ;
67import io .javaoperatorsdk .operator .api .reconciler .Context ;
8+ import io .javaoperatorsdk .operator .api .reconciler .DeleteControl ;
79import io .javaoperatorsdk .operator .api .reconciler .EventSourceContext ;
810import io .javaoperatorsdk .operator .api .reconciler .Reconciler ;
911import io .javaoperatorsdk .operator .api .reconciler .UpdateControl ;
1416import it .aboutbits .postgresql .core .BaseReconciler ;
1517import it .aboutbits .postgresql .core .CRPhase ;
1618import it .aboutbits .postgresql .core .CRStatus ;
17- import it .aboutbits .postgresql .core .KubernetesUtil ;
18- import it .aboutbits .postgresql .core .PostgreSQLAuthenticationUtil ;
19+ import it .aboutbits .postgresql .core .KubernetesService ;
20+ import it .aboutbits .postgresql .core .PostgreSQLAuthenticationService ;
1921import it .aboutbits .postgresql .core .PostgreSQLContextFactory ;
2022import lombok .RequiredArgsConstructor ;
2123import lombok .extern .slf4j .Slf4j ;
3234@ RequiredArgsConstructor
3335public class RoleReconciler
3436 extends BaseReconciler <Role , CRStatus >
35- implements Reconciler <Role > {
37+ implements Reconciler <Role >, Cleaner <Role > {
38+ private final RoleService roleService ;
39+ private final KubernetesService kubernetesService ;
40+ private final PostgreSQLAuthenticationService postgreSQLAuthenticationService ;
41+
3642 private final KubernetesClient kubernetesClient ;
3743 private final PostgreSQLContextFactory contextFactory ;
3844
@@ -84,7 +90,7 @@ public UpdateControl<Role> reconcile(
8490
8591 String password ;
8692 if (passwordSecretRef != null ) {
87- password = KubernetesUtil .getSecretRefCredentials (
93+ password = kubernetesService .getSecretRefCredentials (
8894 kubernetesClient ,
8995 passwordSecretRef ,
9096 namespace
@@ -116,6 +122,70 @@ public UpdateControl<Role> reconcile(
116122 return updateControl ;
117123 }
118124
125+ @ Override
126+ public DeleteControl cleanup (
127+ Role resource ,
128+ Context <Role > context
129+ ) {
130+ var spec = resource .getSpec ();
131+ var status = initializeStatus (resource );
132+
133+ var name = resource .getMetadata ().getName ();
134+ var namespace = resource .getMetadata ().getNamespace ();
135+
136+ log .info (
137+ "Deleting Role [resource={}/{}, spec.name={}, status.phase={}]" ,
138+ namespace ,
139+ name ,
140+ spec .getName (),
141+ status .getPhase ()
142+ );
143+
144+ if (status .getPhase () != CRPhase .DELETING ) {
145+ status .setPhase (CRPhase .DELETING )
146+ .setMessage ("Role deletion in progress" );
147+ }
148+
149+ var clusterRef = spec .getClusterRef ();
150+
151+ var clusterConnectionOptional = getReferencedClusterConnection (
152+ kubernetesClient ,
153+ resource ,
154+ clusterRef
155+ );
156+
157+ if (clusterConnectionOptional .isEmpty ()) {
158+ status .setMessage ("The specified ClusterConnection no longer exists or is not ready yet [clusterRef=%s/%s]" .formatted (
159+ getResourceNamespaceOrOwn (resource , clusterRef .getNamespace ()),
160+ clusterRef .getName ()
161+ ));
162+
163+ return DeleteControl .noFinalizerRemoval ()
164+ .rescheduleAfter (60 , TimeUnit .SECONDS );
165+ }
166+
167+ var clusterConnection = clusterConnectionOptional .get ();
168+
169+ try (var dsl = contextFactory .getDSLContext (clusterConnection )) {
170+ roleService .dropRole (dsl , spec );
171+
172+ return DeleteControl .defaultDelete ();
173+ } catch (Exception e ) {
174+ log .error (
175+ "Failed to delete Role [resource={}/{}, spec.name={}, status.phase={}]" ,
176+ namespace ,
177+ name ,
178+ spec .getName (),
179+ status .getPhase ()
180+ );
181+
182+ status .setMessage ("Deletion failed: " + e .getMessage ());
183+
184+ return DeleteControl .noFinalizerRemoval ()
185+ .rescheduleAfter (60 , TimeUnit .SECONDS );
186+ }
187+ }
188+
119189 /**
120190 * Watches for {@code Secret} changes to trigger reconciliation for dependent {@code Role} resources.
121191 */
@@ -160,14 +230,14 @@ private UpdateControl<Role> reconcileInTransaction(
160230 var expectedFlags = spec .getFlags ();
161231
162232 // Create and return the role if it doesn't exist yet
163- if (!RoleUtil .roleExists (tx , spec )) {
233+ if (!roleService .roleExists (tx , spec )) {
164234 log .info (
165235 "Creating Role [resource={}/{}]" ,
166236 namespace ,
167237 name
168238 );
169239
170- RoleUtil .createRole (
240+ roleService .createRole (
171241 tx ,
172242 spec ,
173243 password
@@ -181,16 +251,16 @@ private UpdateControl<Role> reconcileInTransaction(
181251
182252 // When there is NOLOGIN, we set no password
183253 var passwordMatches = true ;
184- var roleLoginMatches = RoleUtil .roleLoginMatches (tx , spec );
185- var currentFlags = RoleUtil .fetchCurrentFlags (tx , spec );
254+ var roleLoginMatches = roleService .roleLoginMatches (tx , spec );
255+ var currentFlags = roleService .fetchCurrentFlags (tx , spec );
186256 var flagsMatch = expectedFlags .equals (currentFlags );
187- var commentMatches = RoleUtil .roleCommentMatches (tx , spec );
257+ var commentMatches = roleService .roleCommentMatches (tx , spec );
188258
189259 var passwordSecretRef = spec .getPasswordSecretRef ();
190260 var loginExpected = passwordSecretRef != null ;
191261
192262 if (loginExpected && password != null ) {
193- passwordMatches = PostgreSQLAuthenticationUtil .passwordMatches (
263+ passwordMatches = postgreSQLAuthenticationService .passwordMatches (
194264 tx ,
195265 spec ,
196266 password
@@ -216,7 +286,7 @@ private UpdateControl<Role> reconcileInTransaction(
216286 );
217287
218288 if (!roleLoginMatches || !passwordMatches || !flagsMatch ) {
219- RoleUtil .alterRole (
289+ roleService .alterRole (
220290 tx ,
221291 spec ,
222292 changePassword ,
@@ -231,7 +301,7 @@ private UpdateControl<Role> reconcileInTransaction(
231301 name
232302 );
233303
234- RoleUtil .reconcileRoleMembership (
304+ roleService .reconcileRoleMembership (
235305 tx ,
236306 spec ,
237307 expectedFlags ,
@@ -240,7 +310,7 @@ private UpdateControl<Role> reconcileInTransaction(
240310 }
241311
242312 if (!commentMatches ) {
243- RoleUtil .updateComment (
313+ roleService .updateComment (
244314 tx ,
245315 spec
246316 );
0 commit comments