From 54838473040802bde467c6e1e097cc2cf0ceab8c Mon Sep 17 00:00:00 2001 From: "andreas.dinauer" Date: Sun, 9 Nov 2025 00:01:00 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=9A=20Move=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/dev/dinauer/LogResource.java | 76 ------------------- .../{ => inspect/log}/KubernetesLog.java | 2 +- .../{ => inspect/log}/LogWebsocket.java | 3 +- .../websocket}/ResourceEvent.java | 4 +- .../inspect/websocket/ResourceWebsocket.java | 6 -- .../java/dev/dinauer/login/LoginResource.java | 5 +- .../java/dev/dinauer/login/UserCreation.java | 5 ++ .../java/dev/dinauer/login/UserMapper.java | 19 +++++ .../dev/dinauer/{ => login}/UserResource.java | 45 +++++++---- .../monitoring/MonitoringCollection.java | 55 ++++++++++++++ .../monitoring/entity/MonitoringConfig.java | 16 ++++ 11 files changed, 131 insertions(+), 105 deletions(-) delete mode 100644 src/main/java/dev/dinauer/LogResource.java rename src/main/java/dev/dinauer/{ => inspect/log}/KubernetesLog.java (76%) rename src/main/java/dev/dinauer/{ => inspect/log}/LogWebsocket.java (98%) rename src/main/java/dev/dinauer/{ => inspect/websocket}/ResourceEvent.java (56%) create mode 100644 src/main/java/dev/dinauer/login/UserCreation.java create mode 100644 src/main/java/dev/dinauer/login/UserMapper.java rename src/main/java/dev/dinauer/{ => login}/UserResource.java (64%) create mode 100644 src/main/java/dev/dinauer/monitoring/MonitoringCollection.java diff --git a/src/main/java/dev/dinauer/LogResource.java b/src/main/java/dev/dinauer/LogResource.java deleted file mode 100644 index 37ed038..0000000 --- a/src/main/java/dev/dinauer/LogResource.java +++ /dev/null @@ -1,76 +0,0 @@ -package dev.dinauer; - -import dev.dinauer.service.PodService; -import dev.dinauer.utils.ClientProvider; -import io.fabric8.kubernetes.api.model.Pod; -import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.KubernetesClientBuilder; -import io.quarkus.security.Authenticated; -import io.smallrye.common.annotation.Blocking; -import jakarta.annotation.PostConstruct; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.inject.Inject; -import jakarta.ws.rs.*; -import jakarta.ws.rs.core.MediaType; -import org.jboss.resteasy.reactive.common.NotImplementedYet; - -import java.io.IOException; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -@Path("/pods/{pod-id}/logs") -@ApplicationScoped -@Blocking -@Authenticated -public class LogResource -{ - @Inject - ClientProvider clientProvider; - - @Inject - PodService podService; - - @Inject - ProcessRunner processRunner; - - @GET - @Produces(MediaType.APPLICATION_JSON) - public List getLogs(@PathParam("pod-id") String podId) - { - Optional podOptional = podService.findPodById(podId); - if(podOptional.isPresent()) - { - Pod pod = podOptional.get(); - return getLogs(pod, null); - } - throw new NotFoundException(); - } - - public List getLogs(Pod pod, LocalDateTime from) - { - String command = String.format("kubectl logs %s -n %s --timestamps --tail=1000", pod.getMetadata().getName(), pod.getMetadata().getNamespace()); - List result = new ArrayList<>(); - List logs = processRunner.runToLines(command); - for (String log : logs) - { - int indexFirstSpace = log.indexOf(" "); - if (indexFirstSpace != -1) - { - String timestampRaw = log.substring(0, indexFirstSpace); - String message = log.substring(indexFirstSpace).trim(); - try - { - result.add(new KubernetesLog(LocalDateTime.parse(timestampRaw, DateTimeFormatter.ISO_DATE_TIME), message)); - } - catch (Exception e) - { - - } - } - } - return result; - } -} diff --git a/src/main/java/dev/dinauer/KubernetesLog.java b/src/main/java/dev/dinauer/inspect/log/KubernetesLog.java similarity index 76% rename from src/main/java/dev/dinauer/KubernetesLog.java rename to src/main/java/dev/dinauer/inspect/log/KubernetesLog.java index c503202..d29c3c6 100644 --- a/src/main/java/dev/dinauer/KubernetesLog.java +++ b/src/main/java/dev/dinauer/inspect/log/KubernetesLog.java @@ -1,4 +1,4 @@ -package dev.dinauer; +package dev.dinauer.inspect.log; import java.time.LocalDateTime; diff --git a/src/main/java/dev/dinauer/LogWebsocket.java b/src/main/java/dev/dinauer/inspect/log/LogWebsocket.java similarity index 98% rename from src/main/java/dev/dinauer/LogWebsocket.java rename to src/main/java/dev/dinauer/inspect/log/LogWebsocket.java index d7c9199..3567296 100644 --- a/src/main/java/dev/dinauer/LogWebsocket.java +++ b/src/main/java/dev/dinauer/inspect/log/LogWebsocket.java @@ -1,6 +1,5 @@ -package dev.dinauer; +package dev.dinauer.inspect.log; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; diff --git a/src/main/java/dev/dinauer/ResourceEvent.java b/src/main/java/dev/dinauer/inspect/websocket/ResourceEvent.java similarity index 56% rename from src/main/java/dev/dinauer/ResourceEvent.java rename to src/main/java/dev/dinauer/inspect/websocket/ResourceEvent.java index 13c250b..8dbef2e 100644 --- a/src/main/java/dev/dinauer/ResourceEvent.java +++ b/src/main/java/dev/dinauer/inspect/websocket/ResourceEvent.java @@ -1,6 +1,4 @@ -package dev.dinauer; - -import dev.dinauer.inspect.websocket.EventType; +package dev.dinauer.inspect.websocket; import java.util.List; diff --git a/src/main/java/dev/dinauer/inspect/websocket/ResourceWebsocket.java b/src/main/java/dev/dinauer/inspect/websocket/ResourceWebsocket.java index f880fdd..c670d39 100644 --- a/src/main/java/dev/dinauer/inspect/websocket/ResourceWebsocket.java +++ b/src/main/java/dev/dinauer/inspect/websocket/ResourceWebsocket.java @@ -2,32 +2,26 @@ package dev.dinauer.inspect.websocket; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import dev.dinauer.ResourceEvent; import dev.dinauer.ResourceType; import dev.dinauer.service.ResourceService; import dev.dinauer.utils.ClientProvider; import io.fabric8.kubernetes.client.Watch; import io.fabric8.kubernetes.client.Watcher; import io.fabric8.kubernetes.client.WatcherException; -import io.quarkus.security.UnauthorizedException; import io.smallrye.jwt.auth.principal.JWTParser; import io.smallrye.jwt.auth.principal.ParseException; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; -import jakarta.websocket.CloseReason; import jakarta.websocket.OnClose; import jakarta.websocket.OnOpen; import jakarta.websocket.Session; import jakarta.websocket.server.PathParam; import jakarta.websocket.server.ServerEndpoint; -import jakarta.ws.rs.QueryParam; -import jakarta.ws.rs.WebApplicationException; import org.eclipse.microprofile.context.ManagedExecutor; import org.eclipse.microprofile.jwt.JsonWebToken; import org.jboss.logging.Logger; import java.io.IOException; -import java.net.URL; import java.util.HashMap; import java.util.List; import java.util.Map; diff --git a/src/main/java/dev/dinauer/login/LoginResource.java b/src/main/java/dev/dinauer/login/LoginResource.java index 1ad9550..b2c4302 100644 --- a/src/main/java/dev/dinauer/login/LoginResource.java +++ b/src/main/java/dev/dinauer/login/LoginResource.java @@ -9,6 +9,7 @@ import jakarta.inject.Inject; import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; import io.quarkus.elytron.security.common.BcryptUtil; +import jakarta.ws.rs.core.Response; import org.jboss.logging.Logger; import java.io.IOException; @@ -44,9 +45,9 @@ public class LoginResource .sign(); } LOG.info("Cannot access user. Forbidden"); - throw new ForbiddenException(); + throw new ForbiddenException(Response.status(403).type(MediaType.TEXT_PLAIN).entity("wrong_password").build()); } LOG.info("User not found"); - throw new NotFoundException(); + throw new NotFoundException(Response.status(404).type(MediaType.TEXT_PLAIN).entity("user_not_found").build()); } } diff --git a/src/main/java/dev/dinauer/login/UserCreation.java b/src/main/java/dev/dinauer/login/UserCreation.java new file mode 100644 index 0000000..3333615 --- /dev/null +++ b/src/main/java/dev/dinauer/login/UserCreation.java @@ -0,0 +1,5 @@ +package dev.dinauer.login; + +public record UserCreation(String username, String firstname, String lastname, String email, String role, String password) +{ +} diff --git a/src/main/java/dev/dinauer/login/UserMapper.java b/src/main/java/dev/dinauer/login/UserMapper.java new file mode 100644 index 0000000..072f93a --- /dev/null +++ b/src/main/java/dev/dinauer/login/UserMapper.java @@ -0,0 +1,19 @@ +package dev.dinauer.login; + +import jakarta.enterprise.context.ApplicationScoped; + +import java.util.List; + +@ApplicationScoped +public class UserMapper +{ + public User map(UserEntity user) + { + return new User(user.getUsername(), user.getEmail(), user.getRoles(), null); + } + + public List map(List users) + { + return users.stream().map(this::map).toList(); + } +} diff --git a/src/main/java/dev/dinauer/UserResource.java b/src/main/java/dev/dinauer/login/UserResource.java similarity index 64% rename from src/main/java/dev/dinauer/UserResource.java rename to src/main/java/dev/dinauer/login/UserResource.java index 1edddfc..0c77513 100644 --- a/src/main/java/dev/dinauer/UserResource.java +++ b/src/main/java/dev/dinauer/login/UserResource.java @@ -1,11 +1,9 @@ -package dev.dinauer; +package dev.dinauer.login; -import dev.dinauer.login.User; -import dev.dinauer.login.UserEntity; -import dev.dinauer.login.UserRepo; import io.quarkus.elytron.security.common.BcryptUtil; import io.quarkus.security.Authenticated; import io.quarkus.security.identity.SecurityIdentity; +import jakarta.annotation.security.RolesAllowed; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.transaction.Transactional; @@ -13,6 +11,7 @@ import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; import java.io.IOException; +import java.util.List; import java.util.Optional; import java.util.Set; @@ -27,6 +26,9 @@ public class UserResource @Inject SecurityIdentity securityIdentity; + @Inject + UserMapper userMapper; + @GET @Produces(MediaType.APPLICATION_JSON) @Path("/{username}") @@ -35,24 +37,37 @@ public class UserResource Optional userOptional = userRepo.findByIdOptional(id); if (userOptional.isPresent()) { - UserEntity user = userOptional.get(); - return new User(user.getUsername(), user.getEmail(), user.getRoles(), null); + return userMapper.map(userOptional.get()); } throw new NotFoundException(); } + @GET + public List getAll() + { + return userMapper.map(userRepo.listAll()); + } + @POST @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @Transactional - public void createUser(User user) + @RolesAllowed({"ADMIN", "OWNER"}) + public void createUser(UserCreation user) { - UserEntity userEntity = UserEntity.init(); - userEntity.setUsername(user.username()); - userEntity.setPassword(BcryptUtil.bcryptHash(user.password())); - userEntity.setRoles(Set.of("user")); - userEntity.setEmail(user.email()); - userRepo.persist(userEntity); + if (List.of("ADMIN", "USER").contains(user.role())) + { + UserEntity userEntity = UserEntity.init(); + userEntity.setFirstname(user.firstname()); + userEntity.setLastname(user.lastname()); + userEntity.setUsername(user.username()); + userEntity.setPassword(BcryptUtil.bcryptHash(user.password())); + userEntity.setRoles(Set.of(user.role())); + userEntity.setEmail(user.email()); + userRepo.persist(userEntity); + return; + } + throw new RuntimeException("Invalid role."); } @PUT @@ -60,13 +75,13 @@ public class UserResource @Produces @Consumes(MediaType.TEXT_PLAIN) @Transactional - public void changePassword(@PathParam("username") String username, String password) throws IOException + public void changePassword(@PathParam("username") String username, String password) { Optional persistentUserOptional = userRepo.findOptionalByUsername(username); if(persistentUserOptional.isPresent() && password != null && !password.isBlank()) { UserEntity persistentUser = persistentUserOptional.get(); - if(securityIdentity.getPrincipal().getName().equals(persistentUser.getUsername())) + if(securityIdentity.getPrincipal().getName().equals(persistentUser.getId())) { persistentUser.setPassword(BcryptUtil.bcryptHash(password)); userRepo.persist(persistentUser); diff --git a/src/main/java/dev/dinauer/monitoring/MonitoringCollection.java b/src/main/java/dev/dinauer/monitoring/MonitoringCollection.java new file mode 100644 index 0000000..633ee16 --- /dev/null +++ b/src/main/java/dev/dinauer/monitoring/MonitoringCollection.java @@ -0,0 +1,55 @@ +package dev.dinauer.monitoring; + +import dev.dinauer.monitoring.entity.MonitoringConfig; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; + +import java.util.List; + +@Entity +@Table(name = "monitoring_collection") +public class MonitoringCollection +{ + @Id + private String id; + + private String name; + + @OneToMany(mappedBy = "monitoringCollection") + private List configs; + + public String getId() + { + return id; + } + + public MonitoringCollection setId(String id) + { + this.id = id; + return this; + } + + public String getName() + { + return name; + } + + public MonitoringCollection setName(String name) + { + this.name = name; + return this; + } + + public List getConfigs() + { + return configs; + } + + public MonitoringCollection setConfigs(List configs) + { + this.configs = configs; + return this; + } +} diff --git a/src/main/java/dev/dinauer/monitoring/entity/MonitoringConfig.java b/src/main/java/dev/dinauer/monitoring/entity/MonitoringConfig.java index e20e204..70fe892 100644 --- a/src/main/java/dev/dinauer/monitoring/entity/MonitoringConfig.java +++ b/src/main/java/dev/dinauer/monitoring/entity/MonitoringConfig.java @@ -1,5 +1,6 @@ package dev.dinauer.monitoring.entity; +import dev.dinauer.monitoring.MonitoringCollection; import jakarta.persistence.*; @Entity @@ -29,6 +30,10 @@ public class MonitoringConfig @OneToOne(mappedBy = "config") private VolumeConfig volumeConfig; + @ManyToOne + @JoinColumn(name = "monitoring_collection_id") + private MonitoringCollection monitoringCollection; + public String getId() { return id; @@ -116,4 +121,15 @@ public class MonitoringConfig this.volumeConfig = volumeConfig; return this; } + + public MonitoringCollection getMonitoringCollection() + { + return monitoringCollection; + } + + public MonitoringConfig setMonitoringCollection(MonitoringCollection monitoringCollection) + { + this.monitoringCollection = monitoringCollection; + return this; + } }