This is an automated email from the ASF dual-hosted git repository. marat pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-karavan.git
commit 8073ff981e52b6669d190aed12a950de9a18228f Author: Marat Gubaidullin <marat.gubaidul...@gmail.com> AuthorDate: Wed Oct 26 20:22:46 2022 -0400 Redesigned status monitoring --- .../camel/karavan/api/ConfigurationResource.java | 17 ++- .../camel/karavan/api/KubernetesResource.java | 165 ++++++++------------- .../apache/camel/karavan/api/StatusResource.java | 8 +- .../camel/karavan/model/DeploymentStatus.java | 64 ++++---- .../apache/camel/karavan/model/Environment.java | 57 +++++++ .../org/apache/camel/karavan/model/GroupedKey.java | 2 - .../camel/karavan/model/KaravanConfiguration.java | 24 --- .../apache/camel/karavan/model/PipelineStatus.java | 19 ++- .../org/apache/camel/karavan/model/PodStatus.java | 17 ++- .../org/apache/camel/karavan/model/Project.java | 12 +- .../camel/karavan/model/ProjectStoreSchema.java | 2 +- .../apache/camel/karavan/service/GitService.java | 2 +- .../{KaravanService.java => ImportService.java} | 23 +-- .../camel/karavan/service/InfinispanService.java | 99 +++++++++---- .../camel/karavan/service/KaravanService.java | 108 +++----------- .../camel/karavan/service/KubernetesService.java | 131 +++++++--------- .../camel/karavan/service/StatusService.java | 21 ++- .../camel/karavan/watcher/DeploymentWatcher.java | 59 +++++--- .../camel/karavan/watcher/PipelineRunWatcher.java | 7 +- .../apache/camel/karavan/watcher/PodWatcher.java | 12 +- .../src/main/resources/application.properties | 28 +--- karavan-app/src/main/webapp/package-lock.json | 6 +- karavan-app/src/main/webapp/src/api/KaravanApi.tsx | 4 +- .../src/main/webapp/src/projects/ProjectInfo.tsx | 2 +- 24 files changed, 422 insertions(+), 467 deletions(-) diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/api/ConfigurationResource.java b/karavan-app/src/main/java/org/apache/camel/karavan/api/ConfigurationResource.java index 9d0b9ed..cf17e9b 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/api/ConfigurationResource.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/api/ConfigurationResource.java @@ -16,7 +16,7 @@ */ package org.apache.camel.karavan.api; -import org.apache.camel.karavan.model.KaravanConfiguration; +import org.apache.camel.karavan.service.InfinispanService; import org.eclipse.microprofile.config.inject.ConfigProperty; import javax.inject.Inject; @@ -34,8 +34,14 @@ public class ConfigurationResource { @ConfigProperty(name = "karavan.version") String version; + @ConfigProperty(name = "karavan.environment") + String environment; + + @ConfigProperty(name = "karavan.config.runtime") + String runtime; + @Inject - KaravanConfiguration configuration; + InfinispanService infinispanService; @GET @Produces(MediaType.APPLICATION_JSON) @@ -43,10 +49,9 @@ public class ConfigurationResource { return Response.ok( Map.of( "version", version, - "environments", configuration.environments().stream() - .filter(e -> e.active()) - .map(e -> e.name()).collect(Collectors.toList()), - "runtime", configuration.runtime() + "environment", environment, + "environments", infinispanService.getEnvironments().stream().map(e -> e.getName()).collect(Collectors.toList()), + "runtime", runtime ) ).build(); } diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/api/KubernetesResource.java b/karavan-app/src/main/java/org/apache/camel/karavan/api/KubernetesResource.java index e7586a8..a817434 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/api/KubernetesResource.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/api/KubernetesResource.java @@ -17,27 +17,28 @@ package org.apache.camel.karavan.api; import io.smallrye.mutiny.Multi; -import io.vertx.core.json.JsonObject; import io.vertx.mutiny.core.eventbus.EventBus; import io.vertx.mutiny.core.eventbus.Message; -import org.apache.camel.karavan.model.KaravanConfiguration; +import org.apache.camel.karavan.model.DeploymentStatus; import org.apache.camel.karavan.model.Project; import org.apache.camel.karavan.service.InfinispanService; import org.apache.camel.karavan.service.KubernetesService; +import org.eclipse.microprofile.config.inject.ConfigProperty; import org.jboss.logging.Logger; import javax.inject.Inject; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.util.Optional; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; @Path("/api/kubernetes") public class KubernetesResource { @@ -51,162 +52,124 @@ public class KubernetesResource { @Inject KubernetesService kubernetesService; - @Inject - KaravanConfiguration configuration; + @ConfigProperty(name = "karavan.environment") + String environment; + + @ConfigProperty(name = "karavan.pipeline") + String pipeline; + private static final Logger LOGGER = Logger.getLogger(KubernetesResource.class.getName()); @POST @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) - @Path("/pipeline/{environment}") - public Project createPipeline(@PathParam("environment") String environment, Project project) throws Exception { + @Path("/pipeline/{env}") + public Project createPipeline(@PathParam("env") String env, Project project) throws Exception { Project p = infinispanService.getProject(project.getProjectId()); - Optional<KaravanConfiguration.Environment> env = configuration.environments().stream().filter(e -> e.name().equals(environment)).findFirst(); - if (env.isPresent()) { - kubernetesService.createPipelineRun(project, env.get().pipeline(), env.get().namespace()); - p.setDeployed(true); // TODO: Replace this update by updating from Pipeline - infinispanService.saveProject(p); // TODO: Replace this update by updating from Pipeline - } + kubernetesService.createPipelineRun(project, pipeline, kubernetesService.getNamespace()); +// p.setDeployed(true); // TODO: Replace this update by updating from Pipeline +// infinispanService.saveProject(p); // TODO: Replace this update by updating from Pipeline return p; } @GET @Produces(MediaType.APPLICATION_JSON) - @Path("/pipeline/{environment}/{name}") - public Response getPipeline(@PathParam("environment") String environment, - @PathParam("name") String name) throws Exception { - Optional<KaravanConfiguration.Environment> env = configuration.environments().stream().filter(e -> e.name().equals(environment)).findFirst(); - if (env.isPresent()) { - return Response.ok(kubernetesService.getPipelineRun(name, env.get().namespace())).build(); - } else { - return Response.noContent().build(); - } + @Path("/pipeline/{env}/{name}") + public Response getPipeline(@PathParam("env") String env, + @PathParam("name") String name) throws Exception { + return Response.ok(kubernetesService.getPipelineRun(name, kubernetesService.getNamespace())).build(); } @GET @Produces(MediaType.APPLICATION_JSON) - @Path("/pipeline/log/{environment}/{name}") - public Response getPipelineLog(@PathParam("environment") String environment, - @PathParam("name") String name) throws Exception { - Optional<KaravanConfiguration.Environment> env = configuration.environments().stream().filter(e -> e.name().equals(environment)).findFirst(); - if (env.isPresent()) { - return Response.ok(kubernetesService.getPipelineRunLog(name, env.get().namespace())).build(); - } else { - return Response.noContent().build(); - } + @Path("/pipeline/log/{env}/{name}") + public Response getPipelineLog(@PathParam("env") String env, + @PathParam("name") String name) throws Exception { + return Response.ok(kubernetesService.getPipelineRunLog(name, kubernetesService.getNamespace())).build(); } @GET @Produces(MediaType.APPLICATION_JSON) - @Path("/container/log/{environment}/{name}") - public Response getContainerLog(@PathParam("environment") String environment, - @PathParam("name") String name) throws Exception { - Optional<KaravanConfiguration.Environment> env = configuration.environments().stream().filter(e -> e.name().equals(environment)).findFirst(); - if (env.isPresent()) { - return Response.ok(kubernetesService.getContainerLog(name, env.get().namespace())).build(); - } else { - return Response.noContent().build(); - } + @Path("/container/log/{env}/{name}") + public Response getContainerLog(@PathParam("env") String env, + @PathParam("name") String name) throws Exception { + return Response.ok(kubernetesService.getContainerLog(name, kubernetesService.getNamespace())).build(); + } + + @GET + @Produces(MediaType.APPLICATION_JSON) + @Path("/deployment/") + public List<DeploymentStatus> getAll() throws Exception { + return infinispanService.getDeploymentStatuses().stream() + .sorted(Comparator.comparing(DeploymentStatus::getName)) + .collect(Collectors.toList()); } @POST @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) - @Path("/deployment/rollout/{environment}/{name}") - public Response rollout(@PathParam("environment") String environment, @PathParam("name") String name) throws Exception { - Optional<KaravanConfiguration.Environment> env = configuration.environments().stream().filter(e -> e.name().equals(environment)).findFirst(); - if (env.isPresent()) { - kubernetesService.rolloutDeployment(name, env.get().namespace()); - return Response.ok().build(); - } - return Response.noContent().build(); + @Path("/deployment/rollout/{env}/{name}") + public Response rollout(@PathParam("env") String env, @PathParam("name") String name) throws Exception { + kubernetesService.rolloutDeployment(name, kubernetesService.getNamespace()); + return Response.ok().build(); } @DELETE @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) - @Path("/deployment/{environment}/{name}") - public Response deleteDeployment(@PathParam("environment") String environment, @PathParam("name") String name) throws Exception { - Optional<KaravanConfiguration.Environment> env = configuration.environments().stream().filter(e -> e.name().equals(environment)).findFirst(); - if (env.isPresent()) { - kubernetesService.deleteDeployment(name, env.get().namespace()); + @Path("/deployment/{env}/{name}") + public Response deleteDeployment(@PathParam("env") String env, @PathParam("name") String name) throws Exception { + kubernetesService.deleteDeployment(name, kubernetesService.getNamespace()); // Project p = infinispanService.getProject(name); // TODO: p.setDeployed(false) than karavan keeps pod/camel statuses up forever // p.setDeployed(false); // infinispanService.saveProject(p); - return Response.ok().build(); - } - return Response.noContent().build(); + return Response.ok().build(); } @DELETE @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) - @Path("/pod/{environment}/{name}") - public Response deletePod(@PathParam("environment") String environment, @PathParam("name") String name) throws Exception { - Optional<KaravanConfiguration.Environment> env = configuration.environments().stream().filter(e -> e.name().equals(environment)).findFirst(); - if (env.isPresent()) { - kubernetesService.deletePod(name, env.get().namespace()); - return Response.ok().build(); - } - return Response.noContent().build(); + @Path("/pod/{env}/{name}") + public Response deletePod(@PathParam("env") String env, @PathParam("name") String name) throws Exception { + kubernetesService.deletePod(name, kubernetesService.getNamespace()); + return Response.ok().build(); } @GET @Produces(MediaType.APPLICATION_JSON) - @Path("/imagetag/{environment}/{projectId}") - public Response getProjectImageTags(@PathParam("environment") String environment, @PathParam("projectId") String projectId) throws Exception { - Optional<KaravanConfiguration.Environment> env = configuration.environments().stream().filter(e -> e.name().equals(environment)).findFirst(); - if (env.isPresent()) { - return Response.ok(kubernetesService.getProjectImageTags(projectId, env.get().namespace())).build(); - } - return Response.noContent().build(); + @Path("/imagetag/{env}/{projectId}") + public Response getProjectImageTags(@PathParam("env") String env, @PathParam("projectId") String projectId) throws Exception { + return Response.ok(kubernetesService.getProjectImageTags(projectId, kubernetesService.getNamespace())).build(); } @GET @Produces(MediaType.APPLICATION_JSON) - @Path("/configmap/{environment}") - public Response getConfigMaps(@PathParam("environment") String environment) throws Exception { - Optional<KaravanConfiguration.Environment> env = configuration.environments().stream().filter(e -> e.name().equals(environment)).findFirst(); - if (env.isPresent()) { - return Response.ok(kubernetesService.getConfigMaps(env.get().namespace())).build(); - } - return Response.noContent().build(); + @Path("/configmap/{env}") + public Response getConfigMaps(@PathParam("env") String env) throws Exception { + return Response.ok(kubernetesService.getConfigMaps(kubernetesService.getNamespace())).build(); } @GET @Produces(MediaType.APPLICATION_JSON) - @Path("/secret/{environment}") - public Response getSecrets(@PathParam("environment") String environment) throws Exception { - Optional<KaravanConfiguration.Environment> env = configuration.environments().stream().filter(e -> e.name().equals(environment)).findFirst(); - if (env.isPresent()) { - return Response.ok(kubernetesService.getSecrets(env.get().namespace())).build(); - } - return Response.noContent().build(); + @Path("/secret/{env}") + public Response getSecrets(@PathParam("env") String env) throws Exception { + return Response.ok(kubernetesService.getSecrets(kubernetesService.getNamespace())).build(); } @GET @Produces(MediaType.APPLICATION_JSON) - @Path("/service/{environment}") - public Response getServices(@PathParam("environment") String environment) throws Exception { - Optional<KaravanConfiguration.Environment> env = configuration.environments().stream().filter(e -> e.name().equals(environment)).findFirst(); - if (env.isPresent()) { - return Response.ok(kubernetesService.getServices(env.get().namespace())).build(); - } - return Response.noContent().build(); + @Path("/service/{env}") + public Response getServices(@PathParam("env") String env) throws Exception { + return Response.ok(kubernetesService.getServices(kubernetesService.getNamespace())).build(); } // TODO: implement log watch @GET - @Path("/container/log/watch/{environment}/{name}") + @Path("/container/log/watch/{env}/{name}") @Produces(MediaType.SERVER_SENT_EVENTS) - public Multi<String> getContainerLogWatch(@PathParam("environment") String environment, @PathParam("name") String name){ + public Multi<String> getContainerLogWatch(@PathParam("env") String env, @PathParam("name") String name) { LOGGER.info("Start sourcing"); - Optional<KaravanConfiguration.Environment> env = configuration.environments().stream().filter(e -> e.name().equals(environment)).findFirst(); - if (env.isPresent()) { -// eventBus.publish(podName + "-" + namespace, new String(is.readNBytes(i))); -// kubernetesService.startContainerLogWatch(name, env.get().namespace()); - } - return eventBus.<String>consumer(name + "-" + env.get().namespace()).toMulti().map(Message::body); + return eventBus.<String>consumer(name + "-" + kubernetesService.getNamespace()).toMulti().map(Message::body); } } \ No newline at end of file diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java b/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java index b68aaac..f869b26 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java @@ -19,7 +19,6 @@ package org.apache.camel.karavan.api; import io.vertx.core.eventbus.EventBus; import org.apache.camel.karavan.model.CamelStatus; import org.apache.camel.karavan.model.DeploymentStatus; -import org.apache.camel.karavan.model.KaravanConfiguration; import org.apache.camel.karavan.model.PipelineStatus; import org.apache.camel.karavan.service.InfinispanService; import org.apache.camel.karavan.service.StatusService; @@ -27,7 +26,6 @@ import org.jboss.logging.Logger; import javax.inject.Inject; import javax.ws.rs.GET; -import javax.ws.rs.HeaderParam; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @@ -59,9 +57,9 @@ public class StatusResource { @GET @Produces(MediaType.APPLICATION_JSON) - @Path("/deployment/{projectId}") - public Response getDeploymentStatus(@PathParam("projectId") String projectId) { - DeploymentStatus status = infinispanService.getDeploymentStatus(projectId); + @Path("/deployment/{name}/{env}") + public Response getDeploymentStatus(@PathParam("name") String name, @PathParam("env") String env) { + DeploymentStatus status = infinispanService.getDeploymentStatus(name, env); if (status != null) { return Response.ok(status).build(); } else { diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/model/DeploymentStatus.java b/karavan-app/src/main/java/org/apache/camel/karavan/model/DeploymentStatus.java index 732bdb1..c366be1 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/model/DeploymentStatus.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/model/DeploymentStatus.java @@ -3,50 +3,66 @@ package org.apache.camel.karavan.model; import org.infinispan.protostream.annotations.ProtoFactory; import org.infinispan.protostream.annotations.ProtoField; -import java.util.ArrayList; -import java.util.List; - public class DeploymentStatus { public static final String CACHE = "deployment_statuses"; @ProtoField(number = 1) - String projectId; + String name; @ProtoField(number = 2) - String image; + String namespace; @ProtoField(number = 3) - Integer replicas; + String env; @ProtoField(number = 4) - Integer readyReplicas; + String image; @ProtoField(number = 5) + Integer replicas; + @ProtoField(number = 6) + Integer readyReplicas; + @ProtoField(number = 7) Integer unavailableReplicas; - @ProtoField(number = 6, collectionImplementation = ArrayList.class) - List<PodStatus> podStatuses; - - public DeploymentStatus(String projectId) { - this.projectId = projectId; + public DeploymentStatus(String name, String namespace, String env) { + this.name = name; + this.namespace = namespace; + this.env = env; this.image = ""; this.replicas = 0; this.readyReplicas = 0; this.unavailableReplicas = 0; - this.podStatuses = new ArrayList<>(0); } @ProtoFactory - public DeploymentStatus(String projectId, String image, Integer replicas, Integer readyReplicas, Integer unavailableReplicas, List<PodStatus> podStatuses) { - this.projectId = projectId; + public DeploymentStatus(String name, String namespace, String env, String image, Integer replicas, Integer readyReplicas, Integer unavailableReplicas) { + this.name = name; + this.env = env; + this.namespace = namespace; this.image = image; this.replicas = replicas; this.readyReplicas = readyReplicas; this.unavailableReplicas = unavailableReplicas; - this.podStatuses = podStatuses; } - public String getProjectId() { - return projectId; + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; } - public void setProjectId(String projectId) { - this.projectId = projectId; + public String getEnv() { + return env; + } + + public void setEnv(String env) { + this.env = env; + } + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; } public String getImage() { @@ -80,12 +96,4 @@ public class DeploymentStatus { public void setUnavailableReplicas(Integer unavailableReplicas) { this.unavailableReplicas = unavailableReplicas; } - - public List<PodStatus> getPodStatuses() { - return podStatuses; - } - - public void setPodStatuses(List<PodStatus> podStatuses) { - this.podStatuses = podStatuses; - } } diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/model/Environment.java b/karavan-app/src/main/java/org/apache/camel/karavan/model/Environment.java new file mode 100644 index 0000000..e37fbdf --- /dev/null +++ b/karavan-app/src/main/java/org/apache/camel/karavan/model/Environment.java @@ -0,0 +1,57 @@ +package org.apache.camel.karavan.model; + +import org.infinispan.protostream.annotations.ProtoFactory; +import org.infinispan.protostream.annotations.ProtoField; + +public class Environment { + public static final String CACHE = "environments"; + + @ProtoField(number = 1) + String name; + @ProtoField(number = 2) + String cluster; + @ProtoField(number = 3) + String namespace; + @ProtoField(number = 4) + String pipeline; + + @ProtoFactory + public Environment(String name, String cluster, String namespace, String pipeline) { + this.name = name; + this.cluster = cluster; + this.namespace = namespace; + this.pipeline = pipeline; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCluster() { + return cluster; + } + + public void setCluster(String cluster) { + this.cluster = cluster; + } + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } + + public String getPipeline() { + return pipeline; + } + + public void setPipeline(String pipeline) { + this.pipeline = pipeline; + } +} diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/model/GroupedKey.java b/karavan-app/src/main/java/org/apache/camel/karavan/model/GroupedKey.java index c657309..a50e5ce 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/model/GroupedKey.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/model/GroupedKey.java @@ -3,8 +3,6 @@ package org.apache.camel.karavan.model; import org.infinispan.protostream.annotations.ProtoFactory; import org.infinispan.protostream.annotations.ProtoField; -import java.util.Objects; - public class GroupedKey { diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/model/KaravanConfiguration.java b/karavan-app/src/main/java/org/apache/camel/karavan/model/KaravanConfiguration.java deleted file mode 100644 index 5d028c3..0000000 --- a/karavan-app/src/main/java/org/apache/camel/karavan/model/KaravanConfiguration.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.apache.camel.karavan.model; - -import io.smallrye.config.ConfigMapping; - -import java.util.List; - -@ConfigMapping(prefix = "karavan.config") -public interface KaravanConfiguration { - - String groupId(); - String imageGroup(); - String runtime(); - String runtimeVersion(); - Long statusThreshold(); - List<Environment> environments(); - - interface Environment { - String name(); - String cluster(); - String namespace(); - String pipeline(); - Boolean active(); - } -} diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/model/PipelineStatus.java b/karavan-app/src/main/java/org/apache/camel/karavan/model/PipelineStatus.java index 8f6f807..b80c379 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/model/PipelineStatus.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/model/PipelineStatus.java @@ -15,21 +15,22 @@ public class PipelineStatus { String startTime; @ProtoField(number = 6) String completionTime; + @ProtoField(number = 7) + String env; @ProtoFactory - public PipelineStatus(String projectId, String pipelineName, String result, String startTime, String completionTime) { + public PipelineStatus(String projectId, String pipelineName, String result, String startTime, String completionTime, String env) { this.projectId = projectId; this.pipelineName = pipelineName; this.result = result; this.startTime = startTime; this.completionTime = completionTime; + this.env = env; } - public PipelineStatus(String projectId) { + public PipelineStatus(String projectId, String env) { this.projectId = projectId; - } - - public PipelineStatus() { + this.env = env; } public String getProjectId() { @@ -71,4 +72,12 @@ public class PipelineStatus { public void setCompletionTime(String completionTime) { this.completionTime = completionTime; } + + public String getEnv() { + return env; + } + + public void setEnv(String env) { + this.env = env; + } } diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/model/PodStatus.java b/karavan-app/src/main/java/org/apache/camel/karavan/model/PodStatus.java index 7d9c9a4..8c70909 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/model/PodStatus.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/model/PodStatus.java @@ -4,6 +4,7 @@ import org.infinispan.protostream.annotations.ProtoFactory; import org.infinispan.protostream.annotations.ProtoField; public class PodStatus { + public static final String CACHE = "pod_statuses"; @ProtoField(number = 1) String name; @ProtoField(number = 2) @@ -14,22 +15,26 @@ public class PodStatus { String reason; @ProtoField(number = 5) String deployment; + @ProtoField(number = 6) + String env; - public PodStatus() { + public PodStatus(String env) { this.name = ""; this.started = false; this.ready = false; this.reason = ""; this.deployment = ""; + this.env = ""; } @ProtoFactory - public PodStatus(String name, Boolean started, Boolean ready, String reason, String deployment) { + public PodStatus(String name, Boolean started, Boolean ready, String reason, String deployment, String env) { this.name = name; this.started = started; this.ready = ready; this.reason = reason; this.deployment = deployment; + this.env = env; } public String getName() { @@ -71,4 +76,12 @@ public class PodStatus { public void setDeployment(String deployment) { this.deployment = deployment; } + + public String getEnv() { + return env; + } + + public void setEnv(String env) { + this.env = env; + } } diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/model/Project.java b/karavan-app/src/main/java/org/apache/camel/karavan/model/Project.java index 844e07a..898b0ab 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/model/Project.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/model/Project.java @@ -17,8 +17,6 @@ public class Project { Project.CamelRuntime runtime; @ProtoField(number = 5) String lastCommit; - @ProtoField(number = 6) - Boolean deployed; public enum CamelRuntime { @ProtoEnumValue(number = 0, name = "Quarkus") @@ -30,13 +28,12 @@ public class Project { } @ProtoFactory - public Project(String projectId, String name, String description, CamelRuntime runtime, String lastCommit, Boolean deployed) { + public Project(String projectId, String name, String description, CamelRuntime runtime, String lastCommit) { this.projectId = projectId; this.name = name; this.description = description; this.runtime = runtime; this.lastCommit = lastCommit; - this.deployed = deployed; } public Project(String projectId, String name, String description, CamelRuntime runtime) { @@ -89,11 +86,4 @@ public class Project { this.lastCommit = lastCommit; } - public Boolean getDeployed() { - return deployed; - } - - public void setDeployed(Boolean deployed) { - this.deployed = deployed; - } } diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/model/ProjectStoreSchema.java b/karavan-app/src/main/java/org/apache/camel/karavan/model/ProjectStoreSchema.java index 5e8d3d5..6a94007 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/model/ProjectStoreSchema.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/model/ProjectStoreSchema.java @@ -6,7 +6,7 @@ import org.infinispan.protostream.annotations.AutoProtoSchemaBuilder; @AutoProtoSchemaBuilder( includeClasses = { GroupedKey.class, Project.class, ProjectFile.class, PipelineStatus.class, CamelStatus.class, DeploymentStatus.class, - PodStatus.class + PodStatus.class, Environment.class }, schemaPackageName = "karavan") public interface ProjectStoreSchema extends GeneratedSchema { diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/service/GitService.java b/karavan-app/src/main/java/org/apache/camel/karavan/service/GitService.java index 1c12dc1..6780c94 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/service/GitService.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/service/GitService.java @@ -76,7 +76,7 @@ public class GitService { String propertiesPrefix = "karavan." + name + "-"; String branch = ConfigProvider.getConfig().getValue(propertiesPrefix + "git-branch", String.class); if (kubernetesService.inKubernetes()){ - LOGGER.info("inKubernetes " + kubernetesService.currentNamespace); + LOGGER.info("inKubernetes " + kubernetesService.getNamespace()); String kubernetesPrefix = name + "-"; Secret secret = kubernetesService.getKaravanSecret(); String uri = new String(Base64.getDecoder().decode(secret.getData().get(kubernetesPrefix + "git-repository").getBytes(StandardCharsets.UTF_8))); diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java b/karavan-app/src/main/java/org/apache/camel/karavan/service/ImportService.java similarity index 85% copy from karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java copy to karavan-app/src/main/java/org/apache/camel/karavan/service/ImportService.java index 33b2ac0..c83a121 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/service/ImportService.java @@ -16,18 +16,14 @@ */ package org.apache.camel.karavan.service; -import io.quarkus.runtime.StartupEvent; import io.quarkus.vertx.ConsumeEvent; import io.smallrye.mutiny.tuples.Tuple2; -import io.vertx.core.eventbus.EventBus; -import org.apache.camel.karavan.model.KaravanConfiguration; import org.apache.camel.karavan.model.Project; import org.apache.camel.karavan.model.ProjectFile; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.jboss.logging.Logger; import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.event.Observes; import javax.inject.Inject; import java.util.Arrays; import java.util.List; @@ -36,12 +32,11 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; @ApplicationScoped -public class KaravanService { +public class ImportService { - private static final Logger LOGGER = Logger.getLogger(KaravanService.class.getName()); - public static final String START_WATCHERS = "start-watchers"; + private static final Logger LOGGER = Logger.getLogger(ImportService.class.getName()); public static final String IMPORT_PROJECTS = "import-projects"; - public static final String LOAD_CUSTOM_KAMELETS = "load-custom-kamelets"; + public static final String IMPORT_KAMELETS = "import-kamelets"; @Inject InfinispanService infinispanService; @@ -52,13 +47,6 @@ public class KaravanService { @ConfigProperty(name = "karavan.config.runtime") String runtime; - @Inject - KaravanConfiguration configuration; - - void onStart(@Observes StartupEvent ev) { - infinispanService.start(); - } - @ConsumeEvent(value = IMPORT_PROJECTS, blocking = true) void importProjects(String data) { LOGGER.info("Import projects from Git"); @@ -67,7 +55,7 @@ public class KaravanService { repo.forEach(p -> { String folderName = p.getItem1(); String name = Arrays.stream(folderName.split("-")).map(s -> capitalize(s)).collect(Collectors.joining(" ")); - Project project = new Project(folderName, name, name, Project.CamelRuntime.valueOf(runtime.toUpperCase()), "", false); + Project project = new Project(folderName, name, name, Project.CamelRuntime.valueOf(runtime.toUpperCase()), ""); infinispanService.saveProject(project); AtomicReference<ProjectFile> properties = new AtomicReference<>(); @@ -89,10 +77,9 @@ public class KaravanService { } catch (Exception e) { LOGGER.error("Error during project import", e); } - loadCustomKamelets(""); } - @ConsumeEvent(value = LOAD_CUSTOM_KAMELETS, blocking = true) + @ConsumeEvent(value = IMPORT_KAMELETS, blocking = true) void loadCustomKamelets(String data) { LOGGER.info("Load custom Kamelets from Git"); try { diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/service/InfinispanService.java b/karavan-app/src/main/java/org/apache/camel/karavan/service/InfinispanService.java index 136f130..88db2e3 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/service/InfinispanService.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/service/InfinispanService.java @@ -16,13 +16,13 @@ */ package org.apache.camel.karavan.service; -import io.quarkus.runtime.configuration.ProfileManager; -import io.vertx.core.eventbus.EventBus; import org.apache.camel.karavan.model.CamelStatus; import org.apache.camel.karavan.model.DeploymentStatus; +import org.apache.camel.karavan.model.Environment; import org.apache.camel.karavan.model.GroupedKey; import org.apache.camel.karavan.model.Kamelet; import org.apache.camel.karavan.model.PipelineStatus; +import org.apache.camel.karavan.model.PodStatus; import org.apache.camel.karavan.model.Project; import org.apache.camel.karavan.model.ProjectFile; import org.eclipse.microprofile.config.inject.ConfigProperty; @@ -51,16 +51,13 @@ import java.util.stream.Collectors; public class InfinispanService { BasicCache<GroupedKey, Project> projects; - BasicCache<GroupedKey, ProjectFile> files; - BasicCache<GroupedKey, PipelineStatus> pipelineStatuses; - - BasicCache<GroupedKey, DeploymentStatus> deploymentStatus; - - BasicCache<GroupedKey, CamelStatus> camelStatus; - + BasicCache<GroupedKey, DeploymentStatus> deploymentStatuses; + BasicCache<GroupedKey, PodStatus> podStatuses; + BasicCache<GroupedKey, CamelStatus> camelStatuses; BasicCache<String, String> kamelets; + BasicCache<String, Environment> environments; @Inject RemoteCacheManager cacheManager; @@ -68,9 +65,6 @@ public class InfinispanService { @Inject GeneratorService generatorService; - @Inject - EventBus bus; - @ConfigProperty(name = "karavan.config.runtime") String runtime; @@ -95,26 +89,25 @@ public class InfinispanService { .shared(false) .preload(true) .fetchPersistentState(true); + environments = cacheManager.administration().withFlags(CacheContainerAdmin.AdminFlag.VOLATILE).getOrCreateCache(Environment.CACHE, builder.build()); projects = cacheManager.administration().withFlags(CacheContainerAdmin.AdminFlag.VOLATILE).getOrCreateCache(Project.CACHE, builder.build()); files = cacheManager.administration().withFlags(CacheContainerAdmin.AdminFlag.VOLATILE).getOrCreateCache(ProjectFile.CACHE, builder.build()); pipelineStatuses = cacheManager.administration().withFlags(CacheContainerAdmin.AdminFlag.VOLATILE).getOrCreateCache(PipelineStatus.CACHE, builder.build()); - deploymentStatus = cacheManager.administration().withFlags(CacheContainerAdmin.AdminFlag.VOLATILE).getOrCreateCache(DeploymentStatus.CACHE, builder.build()); - camelStatus = cacheManager.administration().withFlags(CacheContainerAdmin.AdminFlag.VOLATILE).getOrCreateCache(CamelStatus.CACHE, builder.build()); + deploymentStatuses = cacheManager.administration().withFlags(CacheContainerAdmin.AdminFlag.VOLATILE).getOrCreateCache(DeploymentStatus.CACHE, builder.build()); + podStatuses = cacheManager.administration().withFlags(CacheContainerAdmin.AdminFlag.VOLATILE).getOrCreateCache(PodStatus.CACHE, builder.build()); + camelStatuses = cacheManager.administration().withFlags(CacheContainerAdmin.AdminFlag.VOLATILE).getOrCreateCache(CamelStatus.CACHE, builder.build()); kamelets = cacheManager.administration().withFlags(CacheContainerAdmin.AdminFlag.VOLATILE).getOrCreateCache(Kamelet.CACHE, builder.build()); } else { LOGGER.info("InfinispanService is starting in remote mode"); + environments = cacheManager.administration().getOrCreateCache(Environment.CACHE, new XMLStringConfiguration(String.format(CACHE_CONFIG, Environment.CACHE))); projects = cacheManager.administration().getOrCreateCache(Project.CACHE, new XMLStringConfiguration(String.format(CACHE_CONFIG, Project.CACHE))); files = cacheManager.administration().getOrCreateCache(ProjectFile.CACHE, new XMLStringConfiguration(String.format(CACHE_CONFIG, ProjectFile.CACHE))); - pipelineStatuses = cacheManager.administration().getOrCreateCache(ProjectFile.CACHE, new XMLStringConfiguration(String.format(CACHE_CONFIG, PipelineStatus.CACHE))); - deploymentStatus = cacheManager.administration().getOrCreateCache(ProjectFile.CACHE, new XMLStringConfiguration(String.format(CACHE_CONFIG, DeploymentStatus.CACHE))); - camelStatus = cacheManager.administration().getOrCreateCache(ProjectFile.CACHE, new XMLStringConfiguration(String.format(CACHE_CONFIG, CamelStatus.CACHE))); + pipelineStatuses = cacheManager.administration().getOrCreateCache(PipelineStatus.CACHE, new XMLStringConfiguration(String.format(CACHE_CONFIG, PipelineStatus.CACHE))); + deploymentStatuses = cacheManager.administration().getOrCreateCache(DeploymentStatus.CACHE, new XMLStringConfiguration(String.format(CACHE_CONFIG, DeploymentStatus.CACHE))); + podStatuses = cacheManager.administration().getOrCreateCache(PodStatus.CACHE, new XMLStringConfiguration(String.format(CACHE_CONFIG, PodStatus.CACHE))); + camelStatuses = cacheManager.administration().getOrCreateCache(CamelStatus.CACHE, new XMLStringConfiguration(String.format(CACHE_CONFIG, CamelStatus.CACHE))); kamelets = cacheManager.administration().getOrCreateCache(Kamelet.CACHE, new XMLStringConfiguration(String.format(CACHE_CONFIG, Kamelet.CACHE))); } - if (getProjects().isEmpty()) { - LOGGER.info("No projects found in the Data Grid"); - bus.publish(KaravanService.IMPORT_PROJECTS, ""); - } - bus.publish(KaravanService.START_WATCHERS, ""); } public List<Project> getProjects() { @@ -171,23 +164,64 @@ public class InfinispanService { } public void savePipelineStatus(PipelineStatus status) { - pipelineStatuses.put(GroupedKey.create(status.getProjectId(), status.getProjectId()), status); + pipelineStatuses.put(GroupedKey.create(status.getProjectId(), status.getEnv()), status); } - public DeploymentStatus getDeploymentStatus(String projectId) { - return deploymentStatus.get(GroupedKey.create(projectId, projectId)); + public DeploymentStatus getDeploymentStatus(String name, String env) { + return deploymentStatuses.get(GroupedKey.create(name, env)); } public void saveDeploymentStatus(DeploymentStatus status) { - deploymentStatus.put(GroupedKey.create(status.getProjectId(), status.getProjectId()), status); + deploymentStatuses.put(GroupedKey.create(status.getName(), status.getEnv()), status); + } + + public void deleteDeploymentStatus(DeploymentStatus status) { + deploymentStatuses.remove(GroupedKey.create(status.getName(), status.getEnv())); + } + + public List<DeploymentStatus> getDeploymentStatuses() { + return deploymentStatuses.values().stream().collect(Collectors.toList()); + } + + public List<DeploymentStatus> getDeploymentStatuses(String env) { + if (cacheManager == null) { + QueryFactory queryFactory = org.infinispan.query.Search.getQueryFactory((Cache<?, ?>) files); + return queryFactory.<DeploymentStatus>create("FROM org.apache.camel.karavan.model.DeploymentStatus WHERE env = :env") + .setParameter("env", env) + .execute().list(); + } else { + QueryFactory queryFactory = Search.getQueryFactory((RemoteCache<?, ?>) files); + return queryFactory.<DeploymentStatus>create("FROM karavan.DeploymentStatus WHERE env = :env") + .setParameter("env", env) + .execute().list(); + } + } + + public List<PodStatus> getPodStatuses(String projectId, String env) { + if (cacheManager == null) { + QueryFactory queryFactory = org.infinispan.query.Search.getQueryFactory((Cache<?, ?>) files); + return queryFactory.<PodStatus>create("FROM org.apache.camel.karavan.model.PodStatus WHERE deployment = :deployment AND env = :env") + .setParameter("deployment", projectId) + .setParameter("env", env) + .execute().list(); + } else { + QueryFactory queryFactory = Search.getQueryFactory((RemoteCache<?, ?>) files); + return queryFactory.<PodStatus>create("FROM karavan.PodStatus WHERE deployment = :deployment AND env = :env") + .setParameter("deployment", projectId) + .setParameter("env", env) + .execute().list(); + } } + public void savePodStatus(PodStatus status) { + podStatuses.put(GroupedKey.create(status.getDeployment(), status.getName()), status); + } public CamelStatus getCamelStatus(String projectId) { - return camelStatus.get(GroupedKey.create(projectId, projectId)); + return camelStatuses.get(GroupedKey.create(projectId, projectId)); } public void saveCamelStatus(CamelStatus status) { - camelStatus.put(GroupedKey.create(status.getProjectId(), status.getProjectId()), status); + camelStatuses.put(GroupedKey.create(status.getProjectId(), status.getProjectId()), status); } public List<String> getKameletNames() { @@ -201,4 +235,13 @@ public class InfinispanService { public void saveKamelet(String name, String yaml) { kamelets.put(name, yaml); } + + public List<Environment> getEnvironments() { + return environments.values().stream().collect(Collectors.toList()); + } + + public void saveEnvironment(Environment environment) { + environments.put(environment.getName(), environment); + } + } diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java b/karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java index 33b2ac0..717e7c5 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java @@ -17,119 +17,57 @@ package org.apache.camel.karavan.service; import io.quarkus.runtime.StartupEvent; -import io.quarkus.vertx.ConsumeEvent; -import io.smallrye.mutiny.tuples.Tuple2; import io.vertx.core.eventbus.EventBus; -import org.apache.camel.karavan.model.KaravanConfiguration; -import org.apache.camel.karavan.model.Project; -import org.apache.camel.karavan.model.ProjectFile; +import org.apache.camel.karavan.model.Environment; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.jboss.logging.Logger; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.event.Observes; import javax.inject.Inject; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicReference; -import java.util.stream.Collectors; @ApplicationScoped public class KaravanService { private static final Logger LOGGER = Logger.getLogger(KaravanService.class.getName()); - public static final String START_WATCHERS = "start-watchers"; - public static final String IMPORT_PROJECTS = "import-projects"; - public static final String LOAD_CUSTOM_KAMELETS = "load-custom-kamelets"; @Inject InfinispanService infinispanService; @Inject - GitService gitService; - - @ConfigProperty(name = "karavan.config.runtime") - String runtime; + KubernetesService kubernetesService; @Inject - KaravanConfiguration configuration; + EventBus bus; + + @ConfigProperty(name = "karavan.environment") + String environment; + + @ConfigProperty(name = "karavan.pipeline") + String pipeline; void onStart(@Observes StartupEvent ev) { infinispanService.start(); + setEnvironment(); + initialImport(); + startInformers(); } - @ConsumeEvent(value = IMPORT_PROJECTS, blocking = true) - void importProjects(String data) { - LOGGER.info("Import projects from Git"); - try { - List<Tuple2<String, Map<String, String>>> repo = gitService.readProjectsFromRepository(); - repo.forEach(p -> { - String folderName = p.getItem1(); - String name = Arrays.stream(folderName.split("-")).map(s -> capitalize(s)).collect(Collectors.joining(" ")); - Project project = new Project(folderName, name, name, Project.CamelRuntime.valueOf(runtime.toUpperCase()), "", false); - infinispanService.saveProject(project); - - AtomicReference<ProjectFile> properties = new AtomicReference<>(); - p.getItem2().forEach((key, value) -> { - ProjectFile file = new ProjectFile(key, value, folderName); - infinispanService.saveProjectFile(file); - if (isApplicationProperties(file)) { - properties.set(file); - } - }); - // update project - if (properties != null){ - project.setDescription(getProjectDescription(properties.get())); - project.setName(getProjectName(properties.get())); - infinispanService.saveProject(project); - } - - }); - } catch (Exception e) { - LOGGER.error("Error during project import", e); - } - loadCustomKamelets(""); + void setEnvironment() { + String cluster = kubernetesService.getCluster(); + String namespace = kubernetesService.getNamespace(); + infinispanService.saveEnvironment(new Environment(environment, cluster, namespace, pipeline)); } - @ConsumeEvent(value = LOAD_CUSTOM_KAMELETS, blocking = true) - void loadCustomKamelets(String data) { - LOGGER.info("Load custom Kamelets from Git"); - try { - List<Tuple2<String, String>> repo = gitService.readKameletsFromRepository(); - repo.forEach(p -> { - String name = p.getItem1(); - String yaml = p.getItem2(); - infinispanService.saveKamelet(name, yaml); - }); - } catch (Exception e) { - LOGGER.error("Error during project import", e); + void initialImport() { + if (infinispanService.getProjects().isEmpty()) { + LOGGER.info("No projects found in the Data Grid"); + bus.publish(ImportService.IMPORT_PROJECTS, ""); } + bus.publish(ImportService.IMPORT_KAMELETS, ""); } - private static String capitalize(String str) { - if(str == null || str.isEmpty()) { - return str; - } - return str.substring(0, 1).toUpperCase() + str.substring(1); - } - - private static boolean isApplicationProperties(ProjectFile file) { - return file.getName().equalsIgnoreCase("application.properties"); - } - - private static String getProperty(ProjectFile file, String property) { - String prefix = property + "="; - return Arrays.stream(file.getCode().split(System.lineSeparator())).filter(s -> s.startsWith(prefix)) - .findFirst().orElseGet(() -> "") - .replace(prefix, ""); - } - - private static String getProjectDescription(ProjectFile file) { - return getProperty(file, "camel.jbang.project-description"); - } - - private static String getProjectName(ProjectFile file) { - return getProperty(file, "camel.jbang.project-name"); + void startInformers() { + bus.publish(KubernetesService.START_WATCHERS, ""); } } diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java b/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java index 20bac71..626eb93 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/service/KubernetesService.java @@ -40,9 +40,7 @@ import io.quarkus.runtime.ShutdownEvent; import io.quarkus.vertx.ConsumeEvent; import io.vertx.mutiny.core.eventbus.EventBus; import org.apache.camel.karavan.model.DeploymentStatus; -import org.apache.camel.karavan.model.KaravanConfiguration; import org.apache.camel.karavan.model.PipelineRunLog; -import org.apache.camel.karavan.model.PodStatus; import org.apache.camel.karavan.model.Project; import org.apache.camel.karavan.watcher.DeploymentWatcher; import org.apache.camel.karavan.watcher.PipelineRunWatcher; @@ -61,22 +59,17 @@ import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Optional; import java.util.stream.Collectors; -import static org.apache.camel.karavan.service.KaravanService.START_WATCHERS; @ApplicationScoped public class KubernetesService { - @Inject - EventBus eventBus; - - @ConfigProperty(name = "kubernetes.namespace", defaultValue = "localhost") - String currentNamespace; + private static final Logger LOGGER = Logger.getLogger(KubernetesService.class.getName()); + public static final String START_WATCHERS = "start-watchers"; @Inject - KaravanConfiguration config; + EventBus eventBus; @Inject InfinispanService infinispanService; @@ -96,36 +89,33 @@ public class KubernetesService { return kubernetesClient().adapt(OpenShiftClient.class); } - private static final Logger LOGGER = Logger.getLogger(KubernetesService.class.getName()); + @ConfigProperty(name = "karavan.environment") + public + String environment; private List<Watch> watches = new ArrayList<>(); @ConsumeEvent(value = START_WATCHERS, blocking = true) void start(String data) { LOGGER.info("Start KubernetesService"); - Optional<KaravanConfiguration.Environment> env = config.environments().stream() - .filter(environment -> environment.name().equals("dev")).findFirst(); - if (env.isPresent()) { - String labelName = getRuntimeLabel(); - try { - watches.add(kubernetesClient().apps().deployments().inNamespace(currentNamespace).withLabel(labelName, "camel") - .watch(new DeploymentWatcher(infinispanService, this))); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } - try { - watches.add(kubernetesClient().pods().inNamespace(currentNamespace).withLabel(labelName, "camel") - .watch(new PodWatcher(infinispanService, this))); - } catch (Exception e){ - LOGGER.error(e.getMessage()); - } - try { - watches.add(tektonClient().v1beta1().pipelineRuns().inNamespace(currentNamespace) - .watch(new PipelineRunWatcher(infinispanService))); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } - + String labelName = getRuntimeLabel(); + try { + watches.add(kubernetesClient().apps().deployments().inNamespace(getNamespace()).withLabel(labelName, "camel") + .watch(new DeploymentWatcher(infinispanService, this))); + } catch (Exception e) { + LOGGER.error(e.getMessage()); + } + try { + watches.add(kubernetesClient().pods().inNamespace(getNamespace()).withLabel(labelName, "camel") + .watch(new PodWatcher(infinispanService, this))); + } catch (Exception e){ + LOGGER.error(e.getMessage()); + } + try { + watches.add(tektonClient().v1beta1().pipelineRuns().inNamespace(getNamespace()) + .watch(new PipelineRunWatcher(infinispanService, this))); + } catch (Exception e) { + LOGGER.error(e.getMessage()); } } @@ -242,49 +232,27 @@ public class KubernetesService { } } - public DeploymentStatus getDeploymentStatus(String name, Deployment deployment) { - try { - String dsImage = deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getImage(); - String imageName = dsImage.startsWith("image-registry.openshift-image-registry.svc") - ? dsImage.replace("image-registry.openshift-image-registry.svc:5000/", "") - : dsImage; - - List<PodStatus> podStatuses = getDeploymentPodsStatuses(name, deployment.getMetadata().getNamespace()); - - return new DeploymentStatus( - name, - imageName, - deployment.getSpec().getReplicas(), - deployment.getStatus().getReadyReplicas(), - deployment.getStatus().getUnavailableReplicas(), - podStatuses - ); - } catch (Exception ex) { - LOGGER.error(ex.getMessage()); - return new DeploymentStatus(name); - } - } - public List<PodStatus> getDeploymentPodsStatuses(String name, String namespace) { - try { - String labelName = getRuntimeLabel(); - List<Pod> pods = kubernetesClient().pods().inNamespace(namespace) - .withLabel("app.kubernetes.io/name", name) - .withLabel(labelName, "camel") - .list().getItems(); - - return pods.stream().map(pod -> new PodStatus( - pod.getMetadata().getName(), - pod.getStatus().getContainerStatuses().get(0).getStarted(), - pod.getStatus().getContainerStatuses().get(0).getReady(), - getPodReason(pod), - pod.getMetadata().getLabels().get("app.kubernetes.io/name") - )).collect(Collectors.toList()); - } catch (Exception ex) { - LOGGER.error(ex.getMessage()); - return List.of(); - } - } +// public List<PodStatus> getDeploymentPodsStatuses(String name, String namespace) { +// try { +// String labelName = getRuntimeLabel(); +// List<Pod> pods = kubernetesClient().pods().inNamespace(namespace) +// .withLabel("app.kubernetes.io/name", name) +// .withLabel(labelName, "camel") +// .list().getItems(); +// +// return pods.stream().map(pod -> new PodStatus( +// pod.getMetadata().getName(), +// pod.getStatus().getContainerStatuses().get(0).getStarted(), +// pod.getStatus().getContainerStatuses().get(0).getReady(), +// getPodReason(pod), +// pod.getMetadata().getLabels().get("app.kubernetes.io/name") +// )).collect(Collectors.toList()); +// } catch (Exception ex) { +// LOGGER.error(ex.getMessage()); +// return List.of(); +// } +// } public Deployment getDeployment(String name, String namespace) { try { @@ -370,7 +338,7 @@ public class KubernetesService { } public Secret getKaravanSecret() { - return kubernetesClient().secrets().inNamespace(currentNamespace).withName("karavan").get(); + return kubernetesClient().secrets().inNamespace(getNamespace()).withName("karavan").get(); } public String getRuntimeLabel() { @@ -381,7 +349,14 @@ public class KubernetesService { return kubernetesClient().isAdaptable(OpenShiftClient.class); } + public String getCluster() { + return kubernetesClient().getMasterUrl().getHost(); + } + public String getNamespace() { + return kubernetesClient().getNamespace(); + } + public boolean inKubernetes() { - return !Objects.equals(currentNamespace, "localhost"); + return !Objects.equals(getNamespace(), "localhost"); } } diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/service/StatusService.java b/karavan-app/src/main/java/org/apache/camel/karavan/service/StatusService.java index 33cc888..a103326 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/service/StatusService.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/service/StatusService.java @@ -24,7 +24,7 @@ import io.vertx.mutiny.core.buffer.Buffer; import io.vertx.mutiny.ext.web.client.HttpResponse; import io.vertx.mutiny.ext.web.client.WebClient; import org.apache.camel.karavan.model.CamelStatus; -import org.apache.camel.karavan.model.KaravanConfiguration; +import org.eclipse.microprofile.config.inject.ConfigProperty; import org.jboss.logging.Logger; import javax.enterprise.context.ApplicationScoped; @@ -45,8 +45,8 @@ public class StatusService { @Inject KubernetesService kubernetesService; - @Inject - KaravanConfiguration configuration; + @ConfigProperty(name = "karavan.camel-status-threshold") + int threshold; private long lastCollect = 0; @@ -65,21 +65,18 @@ public class StatusService { @ConsumeEvent(value = CMD_COLLECT_STATUSES, blocking = true, ordered = true) public void collectStatuses(String projectId) throws Exception { - if ((System.currentTimeMillis() - lastCollect) > configuration.statusThreshold()) { + if ((System.currentTimeMillis() - lastCollect) > threshold) { collectStatusesForProject(projectId); lastCollect = System.currentTimeMillis(); } } private void collectStatusesForProject(String projectId) { - configuration.environments().stream().filter(e -> e.active()).forEach(e -> { - String url = ProfileManager.getActiveProfile().equals("dev") - ? String.format("http://%s-%s.%s/q/health", projectId, e.namespace(), e.cluster()) - : String.format("http://%s.%s.%s/q/health", projectId, e.namespace(), e.cluster()); - CamelStatus cs = getCamelStatus(projectId, url); - infinispanService.saveCamelStatus(cs); - }); - + String url = ProfileManager.getActiveProfile().equals("dev") + ? String.format("http://%s-%s.%s/q/health", projectId, kubernetesService.getNamespace(), kubernetesService.getCluster()) + : String.format("http://%s.%s.%s/q/health", projectId, kubernetesService.getNamespace(), kubernetesService.getCluster()); + CamelStatus cs = getCamelStatus(projectId, url); + infinispanService.saveCamelStatus(cs); } private CamelStatus getCamelStatus(String projectId, String url) { diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/watcher/DeploymentWatcher.java b/karavan-app/src/main/java/org/apache/camel/karavan/watcher/DeploymentWatcher.java index 8f635f3..3177e1e 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/watcher/DeploymentWatcher.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/watcher/DeploymentWatcher.java @@ -26,29 +26,42 @@ public class DeploymentWatcher implements Watcher<Deployment> { @Override public void eventReceived(Watcher.Action action, Deployment deployment) { LOGGER.info(action.name() + " " + deployment.getMetadata().getName()); - Project project = infinispanService.getProject(deployment.getMetadata().getName()); - if (project != null) { - switch (action.name()) { - case "ADDED": - project.setDeployed(true); - infinispanService.saveProject(project); - DeploymentStatus s = kubernetesService.getDeploymentStatus(project.getProjectId(), deployment); - infinispanService.saveDeploymentStatus(s); - break; - case "MODIFIED": - if (!project.getDeployed()) { - project.setDeployed(true); - infinispanService.saveProject(project); - } - DeploymentStatus ds = kubernetesService.getDeploymentStatus(project.getProjectId(), deployment); - infinispanService.saveDeploymentStatus(ds); - break; - case "DELETED": - project.setDeployed(false); - infinispanService.saveProject(project); - infinispanService.saveDeploymentStatus(new DeploymentStatus(project.getProjectId())); - break; - } + DeploymentStatus ds = getDeploymentStatus(deployment); + switch (action.name()) { + case "ADDED": + infinispanService.saveDeploymentStatus(ds); + break; + case "MODIFIED": + infinispanService.saveDeploymentStatus(ds); + break; + case "DELETED": + infinispanService.deleteDeploymentStatus(ds); + break; + } + } + + public DeploymentStatus getDeploymentStatus(Deployment deployment) { + try { + String dsImage = deployment.getSpec().getTemplate().getSpec().getContainers().get(0).getImage(); + String imageName = dsImage.startsWith("image-registry.openshift-image-registry.svc") + ? dsImage.replace("image-registry.openshift-image-registry.svc:5000/", "") + : dsImage; + + return new DeploymentStatus( + deployment.getMetadata().getName(), + deployment.getMetadata().getNamespace(), + kubernetesService.environment, + imageName, + deployment.getSpec().getReplicas(), + deployment.getStatus().getReadyReplicas(), + deployment.getStatus().getUnavailableReplicas() + ); + } catch (Exception ex) { + LOGGER.error(ex.getMessage()); + return new DeploymentStatus( + deployment.getMetadata().getName(), + deployment.getMetadata().getNamespace(), + kubernetesService.environment); } } diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/watcher/PipelineRunWatcher.java b/karavan-app/src/main/java/org/apache/camel/karavan/watcher/PipelineRunWatcher.java index df966a3..1e1ba3a 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/watcher/PipelineRunWatcher.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/watcher/PipelineRunWatcher.java @@ -6,6 +6,7 @@ import io.fabric8.tekton.pipeline.v1beta1.PipelineRun; import org.apache.camel.karavan.model.PipelineStatus; import org.apache.camel.karavan.model.Project; import org.apache.camel.karavan.service.InfinispanService; +import org.apache.camel.karavan.service.KubernetesService; import org.jboss.logging.Logger; import java.time.Instant; @@ -15,9 +16,11 @@ public class PipelineRunWatcher implements Watcher<PipelineRun> { private static final Logger LOGGER = Logger.getLogger(PipelineRunWatcher.class.getName()); private InfinispanService infinispanService; + private KubernetesService kubernetesService; - public PipelineRunWatcher(InfinispanService infinispanService) { + public PipelineRunWatcher(InfinispanService infinispanService, KubernetesService kubernetesService) { this.infinispanService = infinispanService; + this.kubernetesService = kubernetesService; } @Override @@ -28,7 +31,7 @@ public class PipelineRunWatcher implements Watcher<PipelineRun> { Project project = infinispanService.getProject(projectId); if (project != null && List.of("MODIFIED", "ADDED").contains(action.name())) { PipelineStatus pipelineStatus = infinispanService.getPipelineStatus(projectId); - if (pipelineStatus == null) pipelineStatus = new PipelineStatus(project.getProjectId()); + if (pipelineStatus == null) pipelineStatus = new PipelineStatus(project.getProjectId(), kubernetesService.environment); if (pipelineRun.getStatus() != null) { LOGGER.info(action.name()+ " " + pipelineRun.getMetadata().getName() + " " + pipelineRun.getStatus().getConditions().get(0).getReason()); diff --git a/karavan-app/src/main/java/org/apache/camel/karavan/watcher/PodWatcher.java b/karavan-app/src/main/java/org/apache/camel/karavan/watcher/PodWatcher.java index 23fb200..99e0982 100644 --- a/karavan-app/src/main/java/org/apache/camel/karavan/watcher/PodWatcher.java +++ b/karavan-app/src/main/java/org/apache/camel/karavan/watcher/PodWatcher.java @@ -25,12 +25,12 @@ public class PodWatcher implements Watcher<Pod> { public void eventReceived(Action action, Pod pod) { LOGGER.info(action.name() + " " + pod.getMetadata().getName()); String name = pod.getMetadata().getLabels().get("app.kubernetes.io/name"); - Project project = infinispanService.getProject(name); - Deployment deployment = kubernetesService.getDeployment(name, pod.getMetadata().getNamespace()); - if (project != null && deployment != null) { - DeploymentStatus s = kubernetesService.getDeploymentStatus(project.getProjectId(), deployment); - infinispanService.saveDeploymentStatus(s); - } +// Project project = infinispanService.getProject(name); +// Deployment deployment = kubernetesService.getDeployment(name, pod.getMetadata().getNamespace()); +// if (project != null && deployment != null) { +// DeploymentStatus s = kubernetesService.getDeploymentStatus(project.getProjectId(), deployment); +// infinispanService.saveDeploymentStatus(s); +// } } @Override diff --git a/karavan-app/src/main/resources/application.properties b/karavan-app/src/main/resources/application.properties index a0f2b84..6c1a38c 100644 --- a/karavan-app/src/main/resources/application.properties +++ b/karavan-app/src/main/resources/application.properties @@ -1,4 +1,7 @@ karavan.version=3.18.5 +karavan.environment=dev +karavan.pipeline=karavan-pipeline-build-quarkus +karavan.camel-status-threshold=2000 # Git repository Configuration karavan.projects-git-repository=${GIT_REPOSITORY} @@ -12,34 +15,11 @@ karavan.kamelets-git-username=${GIT_USERNAME} karavan.kamelets-git-password=${GIT_TOKEN} karavan.kamelets-git-branch=main -# Projects configuration +# Projects default configuration karavan.config.group-id=org.camel.karavan.demo karavan.config.image-group=karavan karavan.config.runtime=QUARKUS karavan.config.runtime-version=2.13.3.Final -karavan.config.status-threshold=2000 - -karavan.config.environments[0].name=dev -karavan.config.environments[0].namespace=karavan -karavan.config.environments[0].pipeline=karavan-quarkus -karavan.config.environments[0].cluster=svc.cluster.local -karavan.config.environments[0].active=true - -karavan.config.environments[1].name=test -karavan.config.environments[1].namespace=test -karavan.config.environments[1].pipeline=karavan-quarkus -karavan.config.environments[1].cluster=svc.cluster.local -karavan.config.environments[1].active=false - -karavan.config.environments[2].name=prod -karavan.config.environments[2].namespace=prod -karavan.config.environments[2].pipeline=karavan-quarkus -karavan.config.environments[2].cluster=svc.cluster.local -karavan.config.environments[2].active=false - -%dev.karavan.config.environments[0].cluster=apps.home.myocp.net -%dev.karavan.config.environments[1].cluster=apps.home.myocp.net -%dev.karavan.config.environments[2].cluster=apps.home.myocp.net # Infinispan Server address #quarkus.infinispan-client.server-list=localhost:12345 diff --git a/karavan-app/src/main/webapp/package-lock.json b/karavan-app/src/main/webapp/package-lock.json index 81e84ae..6af2d60 100644 --- a/karavan-app/src/main/webapp/package-lock.json +++ b/karavan-app/src/main/webapp/package-lock.json @@ -47,7 +47,8 @@ "@types/js-yaml": "^4.0.5", "@types/uuid": "^8.3.4", "typescript": "^4.5.5", - "uuid": "8.3.2" + "uuid": "8.3.2", + "yaml": "^2.1.3" }, "devDependencies": { "@types/chai": "^4.3.0", @@ -24573,7 +24574,8 @@ "mocha": "^9.2.0", "ts-node": "^10.4.0", "typescript": "^4.5.5", - "uuid": "8.3.2" + "uuid": "8.3.2", + "yaml": "^2.1.3" } }, "keycloak-js": { diff --git a/karavan-app/src/main/webapp/src/api/KaravanApi.tsx b/karavan-app/src/main/webapp/src/api/KaravanApi.tsx index 0d400b2..50379ba 100644 --- a/karavan-app/src/main/webapp/src/api/KaravanApi.tsx +++ b/karavan-app/src/main/webapp/src/api/KaravanApi.tsx @@ -160,8 +160,8 @@ export class KaravanApi { }); } - static async getProjectDeploymentStatus(projectId: string, after: (status: DeploymentStatus) => void) { - instance.get('/api/status/deployment/' + projectId) + static async getProjectDeploymentStatus(projectId: string, env: string, after: (status: DeploymentStatus) => void) { + instance.get('/api/status/deployment/' + projectId + "/" + env) .then(res => { if (res.status === 200) { after(res.data); diff --git a/karavan-app/src/main/webapp/src/projects/ProjectInfo.tsx b/karavan-app/src/main/webapp/src/projects/ProjectInfo.tsx index 24eed8e..16ce1a3 100644 --- a/karavan-app/src/main/webapp/src/projects/ProjectInfo.tsx +++ b/karavan-app/src/main/webapp/src/projects/ProjectInfo.tsx @@ -85,7 +85,7 @@ export class ProjectInfo extends React.Component<Props, State> { this.setState({key: Math.random().toString(), pipelineStatus: status}); // console.log(status); }); - KaravanApi.getProjectDeploymentStatus(this.props.project.projectId, (status: DeploymentStatus) => { + KaravanApi.getProjectDeploymentStatus(this.props.project.projectId, this.state.environment, (status: DeploymentStatus) => { this.setState({key: Math.random().toString(), deploymentStatus: status}); // console.log(status); });