diff --git a/src/integrationTest/java/net/geant/nmaas/externalservices/kubernetes/KubernetesClusterControllerIntTest.java b/src/integrationTest/java/net/geant/nmaas/externalservices/kubernetes/KubernetesClusterControllerIntTest.java index 9ca59982176993b4fe71e3f3bd1c1e47a44e076e..6b4e7aec59c54baa29a1bc1879ef83e6e34dab61 100644 --- a/src/integrationTest/java/net/geant/nmaas/externalservices/kubernetes/KubernetesClusterControllerIntTest.java +++ b/src/integrationTest/java/net/geant/nmaas/externalservices/kubernetes/KubernetesClusterControllerIntTest.java @@ -22,7 +22,7 @@ public class KubernetesClusterControllerIntTest { private static final String KUBERNETES_CLUSTER_JSON = "{" + - "\"ingress\":{" + + "\"ingress\":{\"id\":null" + "\"controllerConfigOption\":\"USE_EXISTING\"," + "\"supportedIngressClass\":\"ingress-class\"," + "\"publicIngressClass\":\"public\"," + @@ -36,7 +36,7 @@ public class KubernetesClusterControllerIntTest { "\"issuerOrWildcardName\":\"test-issuer\"," + "\"ingressPerDomain\":true" + "}," + - "\"deployment\":{" + + "\"deployment\":{\"id\":null" + "\"namespaceConfigOption\":\"USE_DOMAIN_NAMESPACE\"," + "\"defaultNamespace\":\"test-namespace\"," + "\"defaultStorageClass\":\"storageClass\"," + diff --git a/src/main/java/net/geant/nmaas/externalservices/kubernetes/ClusterManagerController.java b/src/main/java/net/geant/nmaas/externalservices/kubernetes/ClusterManagerController.java index 08d36c62c8243cd8a9f481255af8fabb530b5954..7113cff3ae556aa03b96d98fc81b8f967da453fe 100644 --- a/src/main/java/net/geant/nmaas/externalservices/kubernetes/ClusterManagerController.java +++ b/src/main/java/net/geant/nmaas/externalservices/kubernetes/ClusterManagerController.java @@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -61,7 +62,7 @@ public class ClusterManagerController { } @PreAuthorize("hasRole('ROLE_SYSTEM_ADMIN') || hasRole('ROLE_OPERATOR')") - @PatchMapping("/{id}") + @PutMapping("/{id}") public ClusterManagerView updateKubernetesCluster(@PathVariable Long id, @RequestBody ClusterManagerView view) { return clusterService.updateCluster(view, id); } diff --git a/src/main/java/net/geant/nmaas/externalservices/kubernetes/ClusterService.java b/src/main/java/net/geant/nmaas/externalservices/kubernetes/ClusterService.java index 552e32f8d1b5468c1f0841be59a6975a68bd425d..213c3687089085b6e41c5a241009853f5465daf4 100644 --- a/src/main/java/net/geant/nmaas/externalservices/kubernetes/ClusterService.java +++ b/src/main/java/net/geant/nmaas/externalservices/kubernetes/ClusterService.java @@ -151,9 +151,15 @@ public class ClusterService { ClusterManager updated = entity.get(); updated.setName(cluster.getName()); updated.setDescription(cluster.getDescription()); + updated.setCodename(cluster.getCodename()); updated.setModificationDate(OffsetDateTime.now()); + updated.setIngress( modelMapper.map(cluster.getIngress(), KClusterIngress.class) ); + + updated.setDeployment( modelMapper.map(cluster.getDeployment(), KClusterDeployment.class) ); + + updated = clusterManagerRepository.save(updated); //TODO : implement file update logic - return modelMapper.map( clusterManagerRepository.save(updated), ClusterManagerView.class); + return modelMapper.map( updated, ClusterManagerView.class); } } diff --git a/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/KClusterView.java b/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/KClusterView.java index ce62c2088f4c1f1bc10682dca44ec692bffd63a1..cfe1084e148faead01e45ca8c292ab3f8977959d 100644 --- a/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/KClusterView.java +++ b/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/KClusterView.java @@ -19,6 +19,8 @@ public class KClusterView { @Setter public static class KClusterDeploymentView { + private Long id; + private NamespaceConfigOption namespaceConfigOption; private String defaultNamespace; @@ -44,6 +46,8 @@ public class KClusterView { @Setter public static class KClusterIngressView { + private Long id; + private IngressControllerConfigOption controllerConfigOption; private String supportedIngressClass; diff --git a/src/test/java/net/geant/nmaas/externalservices/kubernetes/ClusterServiceTest.java b/src/test/java/net/geant/nmaas/externalservices/kubernetes/ClusterServiceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b3172e49f35b85452292a684ce99c12b83fe423a --- /dev/null +++ b/src/test/java/net/geant/nmaas/externalservices/kubernetes/ClusterServiceTest.java @@ -0,0 +1,110 @@ +package net.geant.nmaas.externalservices.kubernetes; + +import net.geant.nmaas.externalservices.kubernetes.model.ClusterManager; +import net.geant.nmaas.externalservices.kubernetes.model.ClusterManagerView; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.modelmapper.ModelMapper; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.security.NoSuchAlgorithmException; +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class ClusterServiceTest { + + @Mock + private ClusterManagerRepository clusterManagerRepository; + + @Mock + private KubernetesClusterIngressManager kClusterIngressManager; + + @Mock + private KubernetesClusterDeploymentManager kClusterDeploymentManager; + + @InjectMocks + private ClusterService clusterService; + + private ModelMapper modelMapper = new ModelMapper(); + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + @Test + void getClusterView_validId_returnsClusterManagerView() { + Long id = 1L; + ClusterManager clusterManager = ClusterManager.builder().id(id).name("Cluster").description("Description").build(); + ClusterManagerView clusterManagerView = modelMapper.map(clusterManager, ClusterManagerView.class); + + when(clusterManagerRepository.findById(id)).thenReturn(Optional.of(clusterManager)); + + ClusterManagerView result = clusterService.getClusterView(id); + + assertEquals(clusterManagerView.getName(), result.getName()); + verify(clusterManagerRepository, times(1)).findById(id); + } + + @Test + void getClusterView_invalidId_throwsException() { + Long id = 100L; + when(clusterManagerRepository.findById(id)).thenReturn(Optional.empty()); + + assertThrows(IllegalArgumentException.class, () -> clusterService.getClusterView(id)); + verify(clusterManagerRepository, times(1)).findById(id); + } + + @Test + void getAllClusterView_returnsClusterManagerViews() { + ClusterManager cluster1 = ClusterManager.builder().id(1L).name("Cluster1").build(); + ClusterManager cluster2 = ClusterManager.builder().id(2L).name("Cluster2").build(); + + when(clusterManagerRepository.findAll()).thenReturn(List.of(cluster1, cluster2)); + + List<ClusterManagerView> result = clusterService.getAllClusterView(); + + assertEquals(2, result.size()); + verify(clusterManagerRepository, times(1)).findAll(); + } + +// @Test +// void saveCluster_validInput_savesCluster() throws IOException, NoSuchAlgorithmException { +// MultipartFile multipartFile = mock(MultipartFile.class); +// ClusterManager clusterManager = ClusterManager.builder().name("Cluster").description("Description").build(); +// +// when(clusterManagerRepository.save(any(ClusterManager.class))).thenReturn(clusterManager); +// +// // Load config.yaml from test/resources directory +// ClassLoader classLoader = getClass().getClassLoader(); +// try (var inputStream = classLoader.getResourceAsStream("test/resources/config.yaml")) { +// when(multipartFile.getInputStream()).thenReturn(inputStream); +// +// ClusterManagerView result = clusterService.saveCluster(clusterManager, multipartFile); +// assertEquals(clusterManager.getName(), result.getName()); +// verify(clusterManagerRepository, times(1)).save(clusterManager); +// } +// } +// +// @Test +// void updateCluster_validInput_updatesCluster() { +// Long id = 1L; +// ClusterManager existingCluster = ClusterManager.builder().id(id).name("OldName").build(); +// ClusterManagerView updatedView = ClusterManagerView.builder().id(id).name("NewName").build(); +// +// when(clusterManagerRepository.findById(id)).thenReturn(Optional.of(existingCluster)); +// when(clusterManagerRepository.save(any(ClusterManager.class))).thenReturn(existingCluster); +// +// ClusterManagerView result = clusterService.updateCluster(updatedView, id); +// +// assertEquals("NewName", result.getName()); +// verify(clusterManagerRepository, times(1)).save(any(ClusterManager.class)); +// } +} \ No newline at end of file diff --git a/src/test/resources/config.yaml b/src/test/resources/config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..eb5f83c1d43ab3ac763a1ddd5bd93c2af5247fc0 --- /dev/null +++ b/src/test/resources/config.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +clusters: +- cluster: + certificate-authority-data: <ca-data-here> + server: https://your-k8s-cluster.com + name: <cluster-name> +contexts: +- context: + cluster: <cluster-name> + user: <cluster-name-user> + name: <cluster-name> +current-context: <cluster-name> +kind: Config +preferences: {} +users: +- name: <cluster-name-user> + user: + token: <secret-token-here>