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
new file mode 100644
index 0000000000000000000000000000000000000000..7113cff3ae556aa03b96d98fc81b8f967da453fe
--- /dev/null
+++ b/src/main/java/net/geant/nmaas/externalservices/kubernetes/ClusterManagerController.java
@@ -0,0 +1,70 @@
+package net.geant.nmaas.externalservices.kubernetes;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import net.geant.nmaas.externalservices.kubernetes.model.ClusterManager;
+import net.geant.nmaas.externalservices.kubernetes.model.ClusterManagerView;
+import net.geant.nmaas.externalservices.kubernetes.model.KClusterView;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+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;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+@RestController
+@RequestMapping(value = "/api/management/cluster")
+@RequiredArgsConstructor
+@Slf4j
+public class ClusterManagerController {
+
+    private final ClusterService clusterService;
+
+
+    @PreAuthorize("hasRole('ROLE_SYSTEM_ADMIN') || hasRole('ROLE_OPERATOR')")
+    @GetMapping("/{id}")
+    public ClusterManagerView getKubernetesCluster(@PathVariable Long id) {
+        return clusterService.getClusterView(id);
+    }
+
+    @PreAuthorize("hasRole('ROLE_SYSTEM_ADMIN') || hasRole('ROLE_OPERATOR')")
+    @GetMapping("/all")
+    public List<ClusterManagerView> getAllKubernetesCluster() {
+        return clusterService.getAllClusterView();
+    }
+
+    @PreAuthorize("hasRole('ROLE_SYSTEM_ADMIN') || hasRole('ROLE_OPERATOR')")
+    @PostMapping
+    public ClusterManagerView createKKubernetesCluster(@RequestPart("file") MultipartFile file, @RequestPart("data") String viewString) {
+
+        ObjectMapper objectMapper = new ObjectMapper();
+        ClusterManagerView cluster = null;
+        try {
+            cluster = objectMapper.readValue(viewString, ClusterManagerView.class);
+            log.error("Cluster created");
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException(e);
+        }
+
+        return clusterService.readClusterFile(cluster, file);
+    }
+
+    @PreAuthorize("hasRole('ROLE_SYSTEM_ADMIN') || hasRole('ROLE_OPERATOR')")
+    @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/ClusterManagerRepository.java b/src/main/java/net/geant/nmaas/externalservices/kubernetes/ClusterManagerRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..4279b19ddaf11ea9c89569fb4fbe0de2a67820f6
--- /dev/null
+++ b/src/main/java/net/geant/nmaas/externalservices/kubernetes/ClusterManagerRepository.java
@@ -0,0 +1,9 @@
+package net.geant.nmaas.externalservices.kubernetes;
+
+import net.geant.nmaas.externalservices.kubernetes.model.ClusterManager;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface ClusterManagerRepository extends JpaRepository<ClusterManager, Long> {
+}
diff --git a/src/main/java/net/geant/nmaas/externalservices/kubernetes/ClusterService.java b/src/main/java/net/geant/nmaas/externalservices/kubernetes/ClusterService.java
new file mode 100644
index 0000000000000000000000000000000000000000..213c3687089085b6e41c5a241009853f5465daf4
--- /dev/null
+++ b/src/main/java/net/geant/nmaas/externalservices/kubernetes/ClusterService.java
@@ -0,0 +1,218 @@
+package net.geant.nmaas.externalservices.kubernetes;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import net.geant.nmaas.externalservices.kubernetes.model.ClusterConfigView;
+import net.geant.nmaas.externalservices.kubernetes.model.ClusterManager;
+import net.geant.nmaas.externalservices.kubernetes.model.ClusterManagerView;
+import net.geant.nmaas.externalservices.kubernetes.model.KClusterDeployment;
+import net.geant.nmaas.externalservices.kubernetes.model.KClusterIngress;
+import net.geant.nmaas.externalservices.kubernetes.model.KClusterView;
+import org.modelmapper.ModelMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.security.DigestInputStream;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.time.OffsetDateTime;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class ClusterService {
+
+    private final ClusterManagerRepository clusterManagerRepository;
+    private final ModelMapper modelMapper = new ModelMapper();
+
+    private final KubernetesClusterIngressManager kClusterIngressManager;
+
+    private final KubernetesClusterDeploymentManager kClusterDeploymentManager;
+
+
+    public ClusterManagerView getClusterView(Long id) {
+        Optional<ClusterManager> cluster = clusterManagerRepository.findById(id);
+
+        if (cluster.isPresent()) {
+            return modelMapper.map(cluster.get(), ClusterManagerView.class);
+        } else {
+            throw new IllegalArgumentException("Cluster not found");
+        }
+    }
+
+    public List<ClusterManagerView> getAllClusterView() {
+        List<ClusterManager> clusters = clusterManagerRepository.findAll();
+
+        return clusters.stream().map(c -> modelMapper.map(c, ClusterManagerView.class)).collect(Collectors.toList());
+    }
+
+    public ClusterManager getCluster(Long id) {
+        Optional<ClusterManager> cluster = clusterManagerRepository.findById(id);
+
+        if (cluster.isPresent()) {
+            return cluster.get();
+        } else {
+            throw new IllegalArgumentException("Cluster not found");
+        }
+    }
+
+    public File getFileFromCluster(Long id) {
+        ClusterManager cluster = getCluster(id);
+
+        return new File(cluster.getPathConfigFile());
+    }
+
+    public static String saveFileToTmp(MultipartFile file) throws IOException, NoSuchAlgorithmException {
+        String hash = computeSHA256(file);
+
+        Path tmpDir = Paths.get(System.getProperty("java.io.tmpdir"));
+        Path filePath = tmpDir.resolve(hash + ".yaml");
+
+        Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);
+
+        return filePath.toString();
+    }
+
+    public ClusterManagerView saveCluster(ClusterManager entity, MultipartFile file) throws IOException, NoSuchAlgorithmException {
+        checkRequest(entity);
+
+        String savedPath = saveFileToTmp(file);
+        log.debug("Filed saved in: " + savedPath);
+        entity.setPathConfigFile(savedPath);
+
+        ClusterManager cluster = this.clusterManagerRepository.save(entity);
+        log.debug("Cluster saved: {}", cluster.toString());
+        return modelMapper.map(cluster, ClusterManagerView.class);
+
+    }
+
+    public ClusterManagerView readClusterFile(ClusterManagerView view, MultipartFile file) {
+        checkRequest(view);
+
+        ObjectMapper yamlMapper = new ObjectMapper(new YAMLFactory());
+
+        try {
+            ClusterConfigView configView = yamlMapper.readValue(file.getInputStream(), ClusterConfigView.class);
+
+            log.error("Mapped {}", configView.toString());
+
+            if (configView.getClusters().isEmpty()) {
+                log.error("No clusters info provided in configuration file");
+            } else if (configView.getClusters().size() == 1) {
+                log.error("One cluster provided, create view and return ");
+                KClusterDeployment deployment = modelMapper.map(kClusterDeploymentManager.getKClusterDeploymentView(), KClusterDeployment.class);
+                KClusterIngress ingress = modelMapper.map(kClusterIngressManager.getKClusterIngressView(), KClusterIngress.class);
+                return saveCluster(ClusterManager.builder()
+                                .name(view.getName())
+                                .description(view.getDescription())
+                                .creationDate(OffsetDateTime.now())
+                                .modificationDate(OffsetDateTime.now())
+                                .codename(configView.getClusters().stream().findFirst().get().getName())
+                                .clusterConfigFile(file.toString())
+                                .deployment(deployment)
+                                .ingress(ingress)
+                                .build(),
+                        file);
+
+            } else {
+                log.error("More than 1 cluster provided, not implemented yet");
+            }
+
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
+        }
+
+        return null;
+    }
+
+    public ClusterManagerView updateCluster(ClusterManagerView cluster, Long id ) {
+        Optional<ClusterManager> entity = clusterManagerRepository.findById(id);
+
+
+        if (entity.isPresent()) {
+            checkRequest(entity.get(), cluster, id);
+            if(entity.get().getId().equals(id) && entity.get().getId().equals(cluster.getId())) {
+                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( updated, ClusterManagerView.class);
+
+            }
+        }
+
+
+        throw new IllegalArgumentException("Cluster with id: " + id+ " is missing. Can not update.");
+        }
+
+    private void checkRequest(ClusterManagerView view) {
+        if (view.getName() == null) {
+            throw new IllegalArgumentException("Name of the cluster is null");
+        }
+        if (view.getDescription() == null) {
+            throw new IllegalArgumentException("Description of the cluster is null");
+        }
+    }
+
+    private void checkRequest(ClusterManager entity) {
+        if (entity.getName() == null) {
+            throw new IllegalArgumentException("Name of the cluster is null");
+        }
+        if (entity.getCodename() == null) {
+            throw new IllegalArgumentException("Codename of the cluster is null");
+        }
+        if (entity.getDescription() == null) {
+            throw new IllegalArgumentException("Description of the cluster is null");
+        }
+    }
+
+    private static String computeSHA256(MultipartFile file) throws IOException, NoSuchAlgorithmException {
+        MessageDigest digest = MessageDigest.getInstance("SHA-256");
+        try (InputStream is = file.getInputStream();
+             DigestInputStream dis = new DigestInputStream(is, digest)) {
+            while (dis.read() != -1) {
+            }
+        }
+
+        StringBuilder hexString = new StringBuilder();
+        for (byte b : digest.digest()) {
+            hexString.append(String.format("%02x", b));
+        }
+        return hexString.toString();
+    }
+
+    private void checkRequest(ClusterManager entity, ClusterManagerView view,  Long id) {
+        if (view.getName() == null) {
+            throw new IllegalArgumentException("Name of the cluster is null");
+        }
+        if (view.getCodename() == null) {
+            throw new IllegalArgumentException("Codename of the cluster is null");
+        }
+
+    }
+
+
+}
diff --git a/src/main/java/net/geant/nmaas/externalservices/kubernetes/KubernetesClusterController.java b/src/main/java/net/geant/nmaas/externalservices/kubernetes/KubernetesClusterController.java
index 55fb4ae3b5a8258e3738c581850355ed4b286b3d..40fabaea73d56d20788b06e0ff5a495442d17c08 100644
--- a/src/main/java/net/geant/nmaas/externalservices/kubernetes/KubernetesClusterController.java
+++ b/src/main/java/net/geant/nmaas/externalservices/kubernetes/KubernetesClusterController.java
@@ -1,6 +1,7 @@
 package net.geant.nmaas.externalservices.kubernetes;
 
 import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import net.geant.nmaas.externalservices.kubernetes.model.KClusterView;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.transaction.annotation.Propagation;
diff --git a/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/ClusterConfigView.java b/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/ClusterConfigView.java
new file mode 100644
index 0000000000000000000000000000000000000000..91910be14c7d4511ba95b130a68e54a157f867e2
--- /dev/null
+++ b/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/ClusterConfigView.java
@@ -0,0 +1,134 @@
+package net.geant.nmaas.externalservices.kubernetes.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+public class ClusterConfigView {
+
+    private String apiVersion;
+    private String kind;
+
+    @JsonProperty("current-context")
+    private String currentContext;
+
+    private List<ClusterEntry> clusters;
+    private List<ContextEntry> contexts;
+    private ClusterPreferences preferences;
+    private List<UserEntry> users;
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("ClusterConfigView {").append("\n")
+                .append("  apiVersion: ").append(apiVersion).append("\n")
+                .append("  kind: ").append(kind).append("\n")
+                .append("  currentContext: ").append(currentContext).append("\n")
+                .append("  clusters: ").append(clusters).append("\n")
+                .append("  contexts: ").append(contexts).append("\n")
+                .append("  preferences: ").append(preferences).append("\n")
+                .append("  users: ").append(users).append("\n")
+                .append("}");
+        return sb.toString();
+    }
+    @Getter
+    @Setter
+    @AllArgsConstructor
+    @NoArgsConstructor
+    public static class ClusterEntry {
+        private Cluster cluster;
+        private String name;
+
+        @Override
+        public String toString() {
+            return "\n    ClusterEntry { " +
+                    "name: '" + name + "', " +
+                    "cluster: " + cluster + " }";
+        }
+    }
+
+
+    @Getter
+    @Setter
+    @AllArgsConstructor
+    @NoArgsConstructor
+    public static class Cluster {
+        @JsonProperty("certificate-authority-data")
+        private String certificateAuthorityData;
+        private String server;
+
+        @Override
+        public String toString() {
+            return "{ server: '" + server + "', certificateAuthorityData: " + certificateAuthorityData + " }";
+        }
+    }
+
+    @Getter
+    @Setter
+    @AllArgsConstructor
+    @NoArgsConstructor
+    public static class ContextEntry {
+        private Context context;
+        private String name;
+
+        @Override
+        public String toString() {
+            return "\n    ContextEntry { name: '" + name + "', context: " + context + " }";
+        }
+    }
+
+    @Getter
+    @Setter
+    @AllArgsConstructor
+    @NoArgsConstructor
+    public static class Context {
+        private String cluster;
+        private String user;
+
+        @Override
+        public String toString() {
+            return "{ cluster: '" + cluster + "', user: '" + user + "' }";
+        }
+    }
+
+    @Getter
+    @Setter
+    @AllArgsConstructor
+    public static class ClusterPreferences {
+    }
+
+    @Getter
+    @Setter
+    @AllArgsConstructor
+    @NoArgsConstructor
+    public static class UserEntry {
+        private String name;
+        private UserToken user;
+
+        @Override
+        public String toString() {
+            return "\n    UserEntry { name: '" + name + "', user: " + user + " }";
+        }
+    }
+
+    @Getter
+    @Setter
+    @AllArgsConstructor
+    @NoArgsConstructor
+    public static class UserToken {
+        private String token;
+
+        @Override
+        public String toString() {
+            return "{ token: " + token + " }";
+        }
+    }
+}
diff --git a/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/ClusterManager.java b/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/ClusterManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..c80bf1f332a622d55922b559f01aeb5936170a78
--- /dev/null
+++ b/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/ClusterManager.java
@@ -0,0 +1,77 @@
+package net.geant.nmaas.externalservices.kubernetes.model;
+
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.OneToOne;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.time.OffsetDateTime;
+
+@Entity
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+@Setter
+@Builder
+public class ClusterManager {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @Column(nullable = false)
+    private String name;
+
+    @Column(nullable = false)
+    private String codename;
+
+    @Column(nullable = false)
+    private String description;
+
+    @Column(nullable = false)
+    private OffsetDateTime creationDate;
+
+    @Column(nullable = false)
+    private OffsetDateTime modificationDate;
+
+    @Column(nullable = false)
+    private String clusterConfigFile;
+
+    @Column(nullable = false)
+    private String pathConfigFile;
+
+    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
+    @JoinColumn(name = "ingress_id", referencedColumnName = "id")
+    private KClusterIngress ingress;
+
+    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
+    @JoinColumn(name = "deployment_id", referencedColumnName = "id")
+    private KClusterDeployment deployment;
+
+    @Override
+    public String toString() {
+        return "ClusterManager{" +
+                "id=" + id +
+                ", name='" + name + '\'' +
+                ", codename='" + codename + '\'' +
+                ", description='" + description + '\'' +
+                ", creationDate=" + creationDate +
+                ", modificationDate=" + modificationDate +
+                ", clusterConfigFile='" + clusterConfigFile + '\'' +
+                ", pathConfigFile='" + pathConfigFile + '\'' +
+                ", ingress=" + (ingress != null ? ingress.getId() : "null") +
+                ", deployment=" + (deployment != null ? deployment.getId() : "null") +
+                '}';
+    }
+
+}
diff --git a/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/ClusterManagerView.java b/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/ClusterManagerView.java
new file mode 100644
index 0000000000000000000000000000000000000000..cda78bd3c09481716fd606b4de011e247890a9c1
--- /dev/null
+++ b/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/ClusterManagerView.java
@@ -0,0 +1,37 @@
+package net.geant.nmaas.externalservices.kubernetes.model;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import java.time.OffsetDateTime;
+
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+@Builder
+public class ClusterManagerView {
+
+    private Long id;
+
+    private String name;
+
+    private String codename;
+
+    private String description;
+
+    private OffsetDateTime creationDate;
+
+    private OffsetDateTime modificationDate;
+
+    private String pathConfigFile;
+
+    private KClusterView.KClusterIngressView ingress;
+
+    private KClusterView.KClusterDeploymentView deployment;
+
+}
diff --git a/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/KClusterDeployment.java b/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/KClusterDeployment.java
new file mode 100644
index 0000000000000000000000000000000000000000..c5cee559950464bfe1d12808830d046c0dd6bc6d
--- /dev/null
+++ b/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/KClusterDeployment.java
@@ -0,0 +1,47 @@
+package net.geant.nmaas.externalservices.kubernetes.model;
+
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.OneToOne;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Entity
+@Setter
+@Getter
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class KClusterDeployment {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    private NamespaceConfigOption namespaceConfigOption;
+
+    private String defaultNamespace;
+
+    private String defaultStorageClass;
+
+    private String smtpServerHostname;
+
+    private Integer smtpServerPort;
+
+    private String smtpServerUsername;
+
+    private String smtpServerPassword;
+
+    private String smtpFromDefaultDomain;
+
+    private Boolean forceDedicatedWorkers;
+
+    @OneToOne(mappedBy = "deployment", cascade = CascadeType.ALL)
+    private ClusterManager clusterManager;
+}
diff --git a/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/KClusterIngress.java b/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/KClusterIngress.java
new file mode 100644
index 0000000000000000000000000000000000000000..1c6c5d5eb651df43e67b9d33b9552873c0f38acc
--- /dev/null
+++ b/src/main/java/net/geant/nmaas/externalservices/kubernetes/model/KClusterIngress.java
@@ -0,0 +1,54 @@
+package net.geant.nmaas.externalservices.kubernetes.model;
+
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.OneToOne;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Entity
+@Setter
+@Getter
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class KClusterIngress {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    private IngressControllerConfigOption controllerConfigOption;
+
+    private String supportedIngressClass;
+
+    private String publicIngressClass;
+
+    private String controllerChartName;
+
+    private String controllerChartArchive;
+
+    private IngressResourceConfigOption resourceConfigOption;
+
+    private String externalServiceDomain;
+
+    private String publicServiceDomain;
+
+    private Boolean tlsSupported;
+
+    private IngressCertificateConfigOption certificateConfigOption;
+
+    private String issuerOrWildcardName;
+
+    private Boolean ingressPerDomain;
+
+
+    @OneToOne(mappedBy = "ingress", cascade = CascadeType.ALL)
+    private ClusterManager clusterManager;
+}
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>
diff --git a/src/test/shell/data/i18n/de.json b/src/test/shell/data/i18n/de.json
index 4cce919a9cac8382e13b9c588fabc3776f579988..5fc50ea200a54bc366aadf9296e4a8aea42a5fed 100644
--- a/src/test/shell/data/i18n/de.json
+++ b/src/test/shell/data/i18n/de.json
@@ -169,7 +169,16 @@
     "SMTP_SERVER_HOSTNAME": "Hostname des SMTP-Servers",
     "SMTP_SERVER_PORT": "SMTP-Serverport",
     "SMTP_SERVER_USERNAME": "SMTP-Server Benutzername",
-    "SMTP_SERVER_PASSWORD": "SMTP-Server Passwort"
+    "SMTP_SERVER_PASSWORD": "SMTP-Server Passwort",
+    "TITLE_GENERAL" : "General cluster information",
+    "GENERAL" : "Basic information",
+    "NAME" : "Cluster name",
+    "CODENAME" : "Cluster codename",
+    "ID" : "Cluster id",
+    "DESCRIPTION" : "Description",
+    "CREATION_DATE" : "Creation date",
+    "MODIFICATION_DATE" : "Modification date",
+    "PATH_TO_CONFIG" : "Path to config file"
   },
   "GITLAB": {
     "TITLE": "GitLab Konfiguration",
diff --git a/src/test/shell/data/i18n/en.json b/src/test/shell/data/i18n/en.json
index 8dd9565922a6b8de7d1174ac468ed59421334413..c9e5d44aae23b702ff7c478537b000c1f57c4764 100644
--- a/src/test/shell/data/i18n/en.json
+++ b/src/test/shell/data/i18n/en.json
@@ -169,7 +169,16 @@
     "SMTP_SERVER_HOSTNAME": "SMTP server hostname",
     "SMTP_SERVER_PORT": "SMTP server port",
     "SMTP_SERVER_USERNAME": "SMTP server username",
-    "SMTP_SERVER_PASSWORD": "SMTP server password"
+    "SMTP_SERVER_PASSWORD": "SMTP server password",
+    "TITLE_GENERAL" : "General cluster information",
+    "GENERAL" : "Basic information",
+    "NAME" : "Cluster name",
+    "CODENAME" : "Cluster codename",
+    "ID" : "Cluster id",
+    "DESCRIPTION" : "Description",
+    "CREATION_DATE" : "Creation date",
+    "MODIFICATION_DATE" : "Modification date",
+    "PATH_TO_CONFIG" : "Path to config file"
   },
   "GITLAB": {
     "TITLE": "GitLab configuration",
diff --git a/src/test/shell/data/i18n/fr.json b/src/test/shell/data/i18n/fr.json
index ae72dda76bce23267c94aad13a36c485484d7a6d..62466230380e4afedddeb1c29f834f8c42013f0a 100644
--- a/src/test/shell/data/i18n/fr.json
+++ b/src/test/shell/data/i18n/fr.json
@@ -169,7 +169,16 @@
     "SMTP_SERVER_HOSTNAME": "Nom d'hôte du serveur SMTP",
     "SMTP_SERVER_PORT": "Port du serveur SMTP",
     "SMTP_SERVER_USERNAME": "Nom d'utilisateur du serveur SMTP",
-    "SMTP_SERVER_PASSWORD": "Mot de passe du serveur SMTP"
+    "SMTP_SERVER_PASSWORD": "Mot de passe du serveur SMTP",
+    "TITLE_GENERAL" : "General cluster information",
+    "GENERAL" : "Basic information",
+    "NAME" : "Cluster name",
+    "CODENAME" : "Cluster codename",
+    "ID" : "Cluster id",
+    "DESCRIPTION" : "Description",
+    "CREATION_DATE" : "Creation date",
+    "MODIFICATION_DATE" : "Modification date",
+    "PATH_TO_CONFIG" : "Path to config file"
   },
   "GITLAB": {
     "TITLE": "Configuration de GitLab",
diff --git a/src/test/shell/data/i18n/pl.json b/src/test/shell/data/i18n/pl.json
index 756a41814e2570e2e2a4d1ea75913d20b405b9d8..2ebaa565967cb11a01ce8852a589307c34542530 100644
--- a/src/test/shell/data/i18n/pl.json
+++ b/src/test/shell/data/i18n/pl.json
@@ -169,7 +169,16 @@
     "SMTP_SERVER_HOSTNAME": "Nazwa serwera SMTP",
     "SMTP_SERVER_PORT": "Port serwera SMTP",
     "SMTP_SERVER_USERNAME": "Nazwa użytkownika serwera SMTP",
-    "SMTP_SERVER_PASSWORD": "Hasło użytkownika serwera SMTP"
+    "SMTP_SERVER_PASSWORD": "Hasło użytkownika serwera SMTP",
+    "TITLE_GENERAL" : "Podstawowe ustawienia klastra",
+    "GENERAL" : "Ustawienia klastra",
+    "NAME" : "Nazwa klastra",
+    "CODENAME" : "Nazwa kodowa klastra",
+    "ID" : "Identyfikator",
+    "DESCRIPTION" : "Opis",
+    "CREATION_DATE" : "Data utworzenia",
+    "MODIFICATION_DATE" : "Data modyfikacji",
+    "PATH_TO_CONFIG" : "Ścieżka do pliku konfiguracyjnego"
   },
   "GITLAB": {
     "TITLE": "Konfiguracja GitLab",