diff --git a/src/main/java/de/ozgcloud/operator/keycloak/realm/KeycloakRealmReconciler.java b/src/main/java/de/ozgcloud/operator/keycloak/realm/KeycloakRealmReconciler.java index eb935aa0c85d58745e312f0ee630e8689e8d91c3..961a6dd15eec9c6342ea4bb206fb5ddde33d95c2 100644 --- a/src/main/java/de/ozgcloud/operator/keycloak/realm/KeycloakRealmReconciler.java +++ b/src/main/java/de/ozgcloud/operator/keycloak/realm/KeycloakRealmReconciler.java @@ -48,7 +48,7 @@ public class KeycloakRealmReconciler implements Reconciler<OzgKeycloakRealm>, Cl @Override public UpdateControl<OzgKeycloakRealm> reconcile(OzgKeycloakRealm resource, Context<OzgKeycloakRealm> context) { - + log.info("Realm reconciler reconcile, keep after delete is set to: " + resource.getSpec().isKeepAfterDelete()); try { String realmName = resource.getMetadata().getNamespace(); @@ -70,16 +70,19 @@ public class KeycloakRealmReconciler implements Reconciler<OzgKeycloakRealm>, Cl } @Override - public DeleteControl cleanup(OzgKeycloakRealm resource, Context<OzgKeycloakRealm> context) { - - String realmName = resource.getMetadata().getNamespace(); + public DeleteControl cleanup(OzgKeycloakRealm realm, Context<OzgKeycloakRealm> context) { + log.info("Realm reconciler cleanup, keep after delete is set to: " + realm.getSpec().isKeepAfterDelete()); + if (realm.getSpec().isKeepAfterDelete()) { + return DeleteControl.defaultDelete(); + } + return cleanup(realm); + } + DeleteControl cleanup(OzgKeycloakRealm realm) { + var realmName = realm.getMetadata().getNamespace(); + log.info("Deleting KeycloakRealm " + realmName); try { - - log.info("Deleting KeycloakRealm " + realmName); - service.deleteRealm(realmName); - return DeleteControl.defaultDelete(); } catch (Exception e) { log.log(Level.SEVERE, "Could not delete KeycloakRealm " + realmName, e); diff --git a/src/main/java/de/ozgcloud/operator/keycloak/realm/OzgKeycloakRealmSpec.java b/src/main/java/de/ozgcloud/operator/keycloak/realm/OzgKeycloakRealmSpec.java index 6d5fdeaaa5fe8a02db8fcc3388474f1b0202940e..a3cd548780de7a5f7d6ab934fe100b6f5a4fa4de 100644 --- a/src/main/java/de/ozgcloud/operator/keycloak/realm/OzgKeycloakRealmSpec.java +++ b/src/main/java/de/ozgcloud/operator/keycloak/realm/OzgKeycloakRealmSpec.java @@ -24,6 +24,7 @@ package de.ozgcloud.operator.keycloak.realm; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Builder; @@ -39,5 +40,8 @@ import lombok.Setter; @JsonIgnoreProperties(ignoreUnknown = true) class OzgKeycloakRealmSpec { + @JsonProperty("keep_after_delete") + private boolean keepAfterDelete; + private String displayName; } diff --git a/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserReconciler.java b/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserReconciler.java index 2647a00599257804340e2b6db04cfc4a23121071..956313e4067c5f327b19f798ff82e05916d04359 100644 --- a/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserReconciler.java +++ b/src/main/java/de/ozgcloud/operator/keycloak/user/KeycloakUserReconciler.java @@ -44,7 +44,7 @@ import lombok.extern.java.Log; public class KeycloakUserReconciler implements Reconciler<OzgKeycloakUser>, Cleaner<OzgKeycloakUser> { @Autowired - private KeycloakUserService keycloakUserService; + private KeycloakUserService service; @Autowired private KeycloakUserPreconditionService preconditionService; @@ -54,6 +54,7 @@ public class KeycloakUserReconciler implements Reconciler<OzgKeycloakUser>, Clea var namespace = resource.getMetadata().getNamespace(); log.info(String.format("Reconciling user %s...", userName)); + log.info("User reconciler reconcile, keep after delete is set to: " + resource.getSpec().isKeepAfterDelete()); try { var preconditionError = preconditionService.getPreconditionErrors(resource); @@ -69,7 +70,7 @@ public class KeycloakUserReconciler implements Reconciler<OzgKeycloakUser>, Clea .build(); } - keycloakUserService.createOrUpdateUser(resource.getSpec(), namespace); + service.createOrUpdateUser(resource.getSpec(), namespace); return UserUpdateControlBuilder.fromResource(resource).withStatus(OzgCustomResourceStatus.OK).build(); @@ -87,15 +88,20 @@ public class KeycloakUserReconciler implements Reconciler<OzgKeycloakUser>, Clea } @Override - public DeleteControl cleanup(OzgKeycloakUser resource, Context<OzgKeycloakUser> context) { - var userName = resource.getMetadata().getName(); - var namespace = resource.getMetadata().getNamespace(); + public DeleteControl cleanup(OzgKeycloakUser user, Context<OzgKeycloakUser> context) { + log.info("User reconciler cleanup, keep after delete is set to: " + user.getSpec().isKeepAfterDelete()); + if (user.getSpec().isKeepAfterDelete()) { + return DeleteControl.defaultDelete(); + } + return cleanup(user); + } + DeleteControl cleanup(OzgKeycloakUser user) { + var userName = user.getMetadata().getName(); + var namespace = user.getMetadata().getNamespace(); log.info(String.format("Deleting KeycloakUser %s", userName)); - try { - keycloakUserService.deleteUser(resource.getSpec(), namespace); - + service.deleteUser(user.getSpec(), namespace); return DeleteControl.defaultDelete(); } catch (Exception e) { log.log(Level.SEVERE, String.format("Could not delete user %s in namespace %s", userName, namespace), e); diff --git a/src/main/java/de/ozgcloud/operator/keycloak/user/OzgKeycloakUserSpec.java b/src/main/java/de/ozgcloud/operator/keycloak/user/OzgKeycloakUserSpec.java index 6772217abd978ab14a9c9fb1c222772b47b167a7..d42807f5eea7a48bb368fcbc96c2826356e7d2a4 100644 --- a/src/main/java/de/ozgcloud/operator/keycloak/user/OzgKeycloakUserSpec.java +++ b/src/main/java/de/ozgcloud/operator/keycloak/user/OzgKeycloakUserSpec.java @@ -125,22 +125,4 @@ class OzgKeycloakUserSpec { @JsonProperty("role") private String roleName; } - -// @Getter -// @Setter -// @Builder -// @NoArgsConstructor -// @AllArgsConstructor -// static class KeycloakUserSpecRealmRole { -// -// @JsonProperty("name") -// private String name; -// -// @JsonProperty("description") -// private String description; -// -// @JsonProperty("attributes") -// @Builder.Default -// private Map<String, List<String>> attributes = new HashMap<>(); -// } } diff --git a/src/test/java/de/ozgcloud/operator/keycloak/realm/KeycloakRealmReconcilerTest.java b/src/test/java/de/ozgcloud/operator/keycloak/realm/KeycloakRealmReconcilerTest.java index 87b0020866b39895d02917345cda18d730d8159c..0dc7d458a9d6b86babd1e0ae01de1e84ace55373 100644 --- a/src/test/java/de/ozgcloud/operator/keycloak/realm/KeycloakRealmReconcilerTest.java +++ b/src/test/java/de/ozgcloud/operator/keycloak/realm/KeycloakRealmReconcilerTest.java @@ -26,6 +26,7 @@ package de.ozgcloud.operator.keycloak.realm; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; @@ -33,6 +34,7 @@ import org.mockito.Mock; import org.mockito.Spy; import de.ozgcloud.operator.keycloak.OzgCustomResourceStatus; +import io.javaoperatorsdk.operator.api.reconciler.DeleteControl; class KeycloakRealmReconcilerTest { @@ -43,6 +45,7 @@ class KeycloakRealmReconcilerTest { @Mock private KeycloakRealmService service; + @DisplayName("Reconcile") @Nested class TestReconcile { @@ -70,14 +73,37 @@ class KeycloakRealmReconcilerTest { } } + @DisplayName("Cleanup") @Nested - class TestDelete { + class TestCleanup { + + @DisplayName("with keep_after_delete") + @Nested + class TestWithKeepAfterDelete { + + private final OzgKeycloakRealmSpec realmSpec = OzgKeycloakRealmSpecTestFactory.createBuilder().keepAfterDelete(true).build(); + private final OzgKeycloakRealm realm = OzgKeycloakRealmTestFactory.create(realmSpec); + + @Test + void shouldNotCallService() { + reconciler.cleanup(realm, null); + + verify(service, never()).deleteRealm(OzgKeycloakRealmTestFactory.METADATA_NAMESPACE); + } + + @Test + void shouldReturnDeleteControl() { + var control = reconciler.cleanup(realm, null); + + assertThat(control).usingRecursiveComparison().isEqualTo(DeleteControl.defaultDelete()); + } + } @Test void shouldCallServiceDelete() { - OzgKeycloakRealm realm = OzgKeycloakRealmTestFactory.create(); + var realm = OzgKeycloakRealmTestFactory.create(); - reconciler.cleanup(realm, null); + reconciler.cleanup(realm); verify(service).deleteRealm(OzgKeycloakRealmTestFactory.METADATA_NAMESPACE); } diff --git a/src/test/java/de/ozgcloud/operator/keycloak/realm/OzgKeycloakRealmSpecTestFactory.java b/src/test/java/de/ozgcloud/operator/keycloak/realm/OzgKeycloakRealmSpecTestFactory.java index 5918054dbd3a1c40906b5bface1dd30c7c082d56..52063fb17a6f1465f3a38cab0af5ffc8520628f1 100644 --- a/src/test/java/de/ozgcloud/operator/keycloak/realm/OzgKeycloakRealmSpecTestFactory.java +++ b/src/test/java/de/ozgcloud/operator/keycloak/realm/OzgKeycloakRealmSpecTestFactory.java @@ -26,6 +26,7 @@ package de.ozgcloud.operator.keycloak.realm; public class OzgKeycloakRealmSpecTestFactory { public final static String DISPLAY_NAME = "TestDisplayName"; + public final static boolean KEEP_AFTER_DELETE = false; public static OzgKeycloakRealmSpec create() { return createBuilder().build(); @@ -33,6 +34,7 @@ public class OzgKeycloakRealmSpecTestFactory { public static OzgKeycloakRealmSpec.OzgKeycloakRealmSpecBuilder createBuilder() { return OzgKeycloakRealmSpec.builder() + .keepAfterDelete(KEEP_AFTER_DELETE) .displayName(DISPLAY_NAME); } } diff --git a/src/test/java/de/ozgcloud/operator/keycloak/realm/OzgKeycloakRealmTestFactory.java b/src/test/java/de/ozgcloud/operator/keycloak/realm/OzgKeycloakRealmTestFactory.java index e23492a96a0eb9e9baac13c146e5b3c6442988aa..08df37af33ce01660554ce49115646d855b38c07 100644 --- a/src/test/java/de/ozgcloud/operator/keycloak/realm/OzgKeycloakRealmTestFactory.java +++ b/src/test/java/de/ozgcloud/operator/keycloak/realm/OzgKeycloakRealmTestFactory.java @@ -28,8 +28,16 @@ public class OzgKeycloakRealmTestFactory { public static final String METADATA_NAMESPACE = "TestNamespace"; public static OzgKeycloakRealm create() { + return createWithSpec(OzgKeycloakRealmSpecTestFactory.create()); + } + + public static OzgKeycloakRealm create(OzgKeycloakRealmSpec spec) { + return createWithSpec(spec); + } + + private static OzgKeycloakRealm createWithSpec(OzgKeycloakRealmSpec spec) { var realm = new OzgKeycloakRealm(); - realm.setSpec(OzgKeycloakRealmSpecTestFactory.create()); + realm.setSpec(spec); realm.setStatus(OzgKeycloakRealmStatusTestFactory.create()); realm.getMetadata().setNamespace(METADATA_NAMESPACE); diff --git a/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserReconcilerTest.java b/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserReconcilerTest.java index 08e00e7c07c16ef236281c1b65b87a9087d95e11..58bf7617bcf900e0d619c723dbff903cadd818a7 100644 --- a/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserReconcilerTest.java +++ b/src/test/java/de/ozgcloud/operator/keycloak/user/KeycloakUserReconcilerTest.java @@ -31,6 +31,7 @@ import java.util.Optional; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; @@ -38,15 +39,17 @@ import org.mockito.Mock; import org.mockito.Spy; import de.ozgcloud.operator.keycloak.OzgCustomResourceStatus; +import de.ozgcloud.operator.keycloak.user.OzgKeycloakUserSpec.KeycloakUserSpecUser; +import io.javaoperatorsdk.operator.api.reconciler.DeleteControl; class KeycloakUserReconcilerTest { @Spy @InjectMocks - private KeycloakUserReconciler conciler; + private KeycloakUserReconciler reconciler; @Mock - private KeycloakUserService userService; + private KeycloakUserService service; @Mock private KeycloakUserPreconditionService preconditionService; @@ -63,16 +66,16 @@ class KeycloakUserReconcilerTest { void shouldCallServiceAddUser() { OzgKeycloakUser user = OzgKeycloakUserTestFactory.create(); - conciler.reconcile(user, null); + reconciler.reconcile(user, null); - verify(userService).createOrUpdateUser(user.getSpec(), OzgKeycloakUserTestFactory.METADATA_NAMESPACE); + verify(service).createOrUpdateUser(user.getSpec(), OzgKeycloakUserTestFactory.METADATA_NAMESPACE); } @Test void shouldUpdateStatus() { OzgKeycloakUser user = OzgKeycloakUserTestFactory.create(); - conciler.reconcile(user, null); + reconciler.reconcile(user, null); assertThat(user.getStatus().getStatus()).isEqualTo(OzgCustomResourceStatus.OK); } @@ -87,7 +90,7 @@ class KeycloakUserReconcilerTest { when(preconditionService.getPreconditionErrors(any())).thenReturn(Optional.of(ERROR_MESSAGE)); OzgKeycloakUser user = OzgKeycloakUserTestFactory.create(); - conciler.reconcile(user, null); + reconciler.reconcile(user, null); assertThat(user.getStatus().getMessage()).isEqualTo(ERROR_MESSAGE); } @@ -101,24 +104,49 @@ class KeycloakUserReconcilerTest { @Test void shouldSetErrorStatusOnException() { OzgKeycloakUser user = OzgKeycloakUserTestFactory.create(); - doThrow(new RuntimeException()).when(userService).createOrUpdateUser(any(), any()); + doThrow(new RuntimeException()).when(service).createOrUpdateUser(any(), any()); - conciler.reconcile(user, null); + reconciler.reconcile(user, null); assertThat(user.getStatus().getStatus()).isEqualTo(OzgCustomResourceStatus.ERROR); } } + @DisplayName("Cleanup") @Nested - class TestDeleteUser { + class TestCleanup { + + @DisplayName("with keep_after_delete") + @Nested + class TestWithKeepAfterDelete { + + private final KeycloakUserSpecUser keycloakUser = KeycloakUserSpecUserTestFactory.createBuiler().build(); + private final OzgKeycloakUserSpec userSpec = OzgKeycloakUserSpecTestFactory.createBuilder().keepAfterDelete(true) + .keycloakUser(keycloakUser).build(); + private final OzgKeycloakUser user = OzgKeycloakUserTestFactory.create(userSpec); + + @Test + void shouldNotCallService() { + reconciler.cleanup(user, null); + + verify(service, never()).deleteUser(userSpec, OzgKeycloakUserTestFactory.METADATA_NAMESPACE); + } + + @Test + void shouldReturnDeleteControl() { + var control = reconciler.cleanup(user, null); + + assertThat(control).usingRecursiveComparison().isEqualTo(DeleteControl.defaultDelete()); + } + } @Test - void shouldCallServiceDeleteUser() { - OzgKeycloakUser user = OzgKeycloakUserTestFactory.create(); + void shouldCallServiceDelete() { + var user = OzgKeycloakUserTestFactory.create(); - conciler.cleanup(user, null); + reconciler.cleanup(user); - verify(userService).deleteUser(user.getSpec(), OzgKeycloakUserTestFactory.METADATA_NAMESPACE); + verify(service).deleteUser(user.getSpec(), OzgKeycloakUserTestFactory.METADATA_NAMESPACE); } } } diff --git a/src/test/java/de/ozgcloud/operator/keycloak/user/OzgKeycloakUserTestFactory.java b/src/test/java/de/ozgcloud/operator/keycloak/user/OzgKeycloakUserTestFactory.java index 32cdc69a1bed108d02ba8e8aa1b1f1a92be35860..79677c8c0797c77b3d7460a19db4a672c623a50c 100644 --- a/src/test/java/de/ozgcloud/operator/keycloak/user/OzgKeycloakUserTestFactory.java +++ b/src/test/java/de/ozgcloud/operator/keycloak/user/OzgKeycloakUserTestFactory.java @@ -28,12 +28,19 @@ class OzgKeycloakUserTestFactory { public static final String METADATA_NAMESPACE = "TestNamespace"; public static OzgKeycloakUser create() { + return createWithSpec(OzgKeycloakUserSpecTestFactory.create()); + } + + public static OzgKeycloakUser create(OzgKeycloakUserSpec spec) { + return createWithSpec(spec); + } + + private static OzgKeycloakUser createWithSpec(OzgKeycloakUserSpec spec) { var keycloakUser = new OzgKeycloakUser(); + keycloakUser.setSpec(spec); keycloakUser.setStatus(OzgKeycloakUserStatusTestFactory.create()); - keycloakUser.setSpec(OzgKeycloakUserSpecTestFactory.create()); keycloakUser.getMetadata().setNamespace(METADATA_NAMESPACE); return keycloakUser; } - -} +} \ No newline at end of file